diff --git a/src/backends/NetworkManagerDebian.c b/src/backends/NetworkManagerDebian.c index 740572a..93c2914 100644 --- a/src/backends/NetworkManagerDebian.c +++ b/src/backends/NetworkManagerDebian.c @@ -37,6 +37,7 @@ #include "interface_parser.h" #include "nm-utils.h" #define ARPING "/usr/sbin/arping" +#define RESOLVCONF "resolvconf" /* * nm_system_init @@ -238,14 +239,14 @@ void nm_system_kill_all_dhcp_daemons (vo /* * nm_system_update_dns * - * Make glibc/nscd aware of any changes to the resolv.conf file by - * restarting nscd. + * Invalidate the nscd host cache, if it exists, since + * we changed resolv.conf. * */ void nm_system_update_dns (void) { - nm_spawn_process ("/usr/sbin/invoke-rc.d nscd restart"); - + nm_info ("Clearing nscd hosts cache."); + nm_spawn_process ("/usr/sbin/nscd -i hosts"); } @@ -514,13 +515,60 @@ gboolean nm_system_device_get_use_dhcp ( /* * nm_system_device_get_disabled * - * Return whether the distro-specific system config tells us to use - * dhcp for this device. + * Return whether the distro-specific system config tells us to disable + * this device. * */ gboolean nm_system_device_get_disabled (NMDevice *dev) { - return FALSE; + const char *iface; + if_block *curr_device, *curr_b; + if_data *curr_d; + gboolean blacklist = TRUE; + + g_return_val_if_fail (dev != NULL, TRUE); + + iface = nm_device_get_iface (dev); + + ifparser_init (); + + /* If the device is listed in a mapping, do not control it */ + if (ifparser_getmapping (iface) != NULL) { + blacklist = TRUE; + goto out; + } + + /* If the interface isn't listed in /etc/network/interfaces then + * it's considered okay to control it. + */ + curr_device = ifparser_getif (iface); + if (curr_device == NULL) { + blacklist = FALSE; + goto out; + } + + /* If the interface is listed and isn't marked "auto" then it's + * definitely not okay to control it. + */ + for (curr_b = ifparser_getfirst (); curr_b; curr_b = curr_b->next) { + if ((!strcmp (curr_b->type, "auto") || !strcmp (curr_b->type, "allow-hotplug")) + && strstr (curr_b->name, iface)) + blacklist = FALSE; + } + + /* If the interface has no options other than just "inet dhcp" + * it's probably ok to fiddle with it. + */ + for (curr_d = curr_device->info; curr_d; curr_d = curr_d->next) { + if (strcmp (curr_d->key, "inet") + || strcmp (curr_d->data, "dhcp" )) + blacklist = TRUE; + } + +out: + ifparser_destroy (); + + return blacklist; } @@ -563,12 +611,18 @@ gboolean nm_system_deactivate_dialup (GS if (strcmp (dialup, config->name) == 0) { char *cmd; + int status; nm_info ("Deactivating dialup device %s (%s) ...", dialup, (char *) config->data); cmd = g_strdup_printf ("/sbin/ifdown %s", (char *) config->data); nm_spawn_process (cmd); g_free (cmd); - ret = TRUE; + if (status == 0) { + ret = TRUE; + } else { + nm_warning ("Couldn't deactivate dialup device %s (%s) - %d", dialup, (char *) config->data, status); + ret = FALSE; + } break; } } @@ -587,12 +641,18 @@ gboolean nm_system_activate_dialup (GSLi if (strcmp (dialup, config->name) == 0) { char *cmd; + int status; nm_info ("Activating dialup device %s (%s) ...", dialup, (char *) config->data); cmd = g_strdup_printf ("/sbin/ifup %s", (char *) config->data); nm_spawn_process (cmd); g_free (cmd); - ret = TRUE; + if (status == 0) { + ret = TRUE; + } else { + nm_warning ("Couldn't activate dialup device %s (%s) - %d", dialup, (char *) config->data, status); + ret = FALSE; + } break; } } @@ -603,23 +663,26 @@ gboolean nm_system_activate_dialup (GSLi GSList * nm_system_get_dialup_config (void) { const char *buf; - unsigned int i = 0; + const char *provider; GSList *list = NULL; if_block *curr; ifparser_init(); /* FIXME: get all ppp(and others?) lines from /e/n/i here */ curr = ifparser_getfirst(); - while(curr!=NULL) + while (curr != NULL) { NMDialUpConfig *config; - if (strcmp(curr->type,"iface")==0) + if (strcmp(curr->type, "iface") == 0) { - buf = ifparser_getkey(curr,"inet"); - if (buf && strcmp (buf, "ppp")==0) + buf = ifparser_getkey(curr, "inet"); + if (buf && strcmp (buf, "ppp") == 0) { + provider = ifparser_getkey(curr, "provider"); + if (!provider) + provider = "default provider"; config = g_malloc (sizeof (NMDialUpConfig)); - config->name = g_strdup_printf ("Modem (#%d)", i++); + config->name = g_strdup_printf ("%s via Modem", provider); config->data = g_strdup (curr->name); /* interface name */ list = g_slist_append (list, config); @@ -631,14 +694,6 @@ GSList * nm_system_get_dialup_config (vo } ifparser_destroy(); - /* Hack: Go back and remove the "(#0)" if there is only one device */ - if (i == 1) - { - NMDialUpConfig *config = (NMDialUpConfig *) list->data; - g_free (config->name); - config->name = g_strdup ("Modem"); - } - return list; } @@ -679,7 +734,10 @@ void nm_system_set_hostname (NMIP4Config */ gboolean nm_system_should_modify_resolv_conf (void) { - return TRUE; + if (g_find_program_in_path(RESOLVCONF) != NULL) + return FALSE; + else + return TRUE; } diff --git a/src/backends/interface_parser.c b/src/backends/interface_parser.c index 53d6487..b3ad300 100644 --- a/src/backends/interface_parser.c +++ b/src/backends/interface_parser.c @@ -50,11 +50,13 @@ void add_block(const char *type, const c void add_data(const char *key,const char *data) { + if_data *ret; + // Check if there is a block where we can attach our data if (first == NULL) return; - if_data *ret = (if_data*)calloc(1,sizeof(struct _if_data)); + ret = (if_data*) calloc(1,sizeof(struct _if_data)); ret->key = g_strdup(key); ret->data = g_strdup(data); @@ -71,14 +73,18 @@ void add_data(const char *key,const char //printf("added data '%s' with key '%s'\n",data,key); } -#define SPACE_OR_TAB(string,ret) {ret = strchr(string,' ');ret=(ret == NULL?strchr(string,'\t'):ret);} +// define what we consider a whitespace +#define WS " \t" void ifparser_init(void) { FILE *inp = fopen(INTERFACES,"r"); int ret = 0; + int pos; + int len; char *line; - char *space; + char *key; + char *data; char rline[255]; if (inp == NULL) @@ -89,7 +95,7 @@ void ifparser_init(void) first = last = NULL; while(1) { - line = space = NULL; + line = NULL; ret = fscanf(inp,"%255[^\n]\n",rline); if (ret == EOF) break; @@ -102,50 +108,71 @@ void ifparser_init(void) line = rline; while(line[0] == ' ') line++; - if (line[0]=='#' || line[0]=='\0') + if (line[0] == '#' || line[0] == '\0') continue; - SPACE_OR_TAB(line,space) - if (space == NULL) + len = strlen(line); + pos = 0; + while (!strchr(WS, line[pos]) && pos < len) pos++; + + // terminate key string and skip further whitespaces + line[pos++] = '\0'; + while (strchr(WS, line[pos]) && pos < len) pos++; + + if (pos >= len) { - nm_warning ("Error: Can't parse interface line '%s'\n",line); + nm_warning ("Error: Can't parse line '%s'\n", line); continue; } - space[0] = '\0'; - + key = &line[0]; + data = &line[pos]; + // There are four different stanzas: // iface, mapping, auto and allow-*. Create a block for each of them. - if (strcmp(line,"iface")==0) + if (strcmp(key, "iface") == 0) { - char *space2 = strchr(space+1,' '); - if (space2 == NULL) + char *key2; + + while (!strchr(WS, line[pos]) && pos < len ) pos++; + + // terminate first data string and skip further whitespaces + line[pos++] = '\0'; + while (strchr(WS, line[pos]) && pos < len) pos++; + if (pos >= len) { - nm_warning ("Error: Can't parse iface line '%s'\n",space+1); + nm_warning ("Error: Can't parse iface line '%s'\n", data); continue; } - space2[0]='\0'; - add_block(line,space+1); + key2 = &line[pos]; + + add_block(key, data); - if (space2[1]!='\0') + if (pos < len) { - space = strchr(space2+1,' '); - if (space == NULL) + + while (!strchr(WS, line[pos]) && pos < len ) pos++; + + // terminate key2 string and skip further whitespaces + line[pos++] = '\0'; + while (strchr(WS, line[pos]) && pos < len) pos++; + if (pos >= len) { - nm_warning ("Error: Can't parse data '%s'\n",space2+1); + nm_warning ("Error: Can't parse inet line '%s'\n", key2); continue; } - space[0] = '\0'; - add_data(space2+1,space+1); + data = &line[pos]; + + add_data(key2, data); } } - else if (strcmp(line,"auto")==0) - add_block(line,space+1); - else if (strcmp(line,"mapping")==0) - add_block(line,space+1); - else if (strncmp(line,"allow-",6)==0) - add_block(line,space+1); + else if (strcmp(key, "auto") == 0) + add_block(key, data); + else if (strcmp(key, "mapping") == 0) + add_block(key, data); + else if (strncmp(key, "allow-", 6) == 0) + add_block(key, data); else - add_data(line,space+1); + add_data(key, data); //printf("line: '%s' ret=%d\n",rline,ret); } @@ -198,6 +225,18 @@ if_block *ifparser_getif(const char* ifa return NULL; } +if_block *ifparser_getmapping(const char* iface) +{ + if_block *curr = first; + while(curr!=NULL) + { + if (strcmp(curr->type,"mapping")==0 && strcmp(curr->name,iface)==0) + return curr; + curr = curr->next; + } + return NULL; +} + const char *ifparser_getkey(if_block* iface, const char *key) { if_data *curr = iface->info; diff --git a/src/backends/interface_parser.h b/src/backends/interface_parser.h index 075f454..8914283 100644 --- a/src/backends/interface_parser.h +++ b/src/backends/interface_parser.h @@ -44,6 +44,7 @@ void ifparser_init(void); void ifparser_destroy(void); if_block *ifparser_getif(const char* iface); +if_block *ifparser_getmapping(const char* iface); if_block *ifparser_getfirst(void); const char *ifparser_getkey(if_block* iface, const char *key);