int netcfg_set_passphrase (struct debconfclient *client, struct netcfg_interface *interface) { int ret; debconf_subst(client, "netcfg/wireless_wpa", "iface", interface->name); debconf_input(client, "high", "netcfg/wireless_wpa"); ret = debconf_go(client); if (ret == 30) return GO_BACK; if (interface->passphrase != NULL) free(interface->passphrase); debconf_get(client, "netcfg/wireless_wpa"); interface->passphrase = strdup(client->value); while (strlen(interface->passphrase) < WPA_MIN || strlen(interface->passphrase) > WPA_MAX) { debconf_subst(client, "netcfg/invalid_pass", "passphrase", interface->passphrase); debconf_input(client, "critical", "netcfg/invalid_pass"); debconf_go(client); free(interface->passphrase); debconf_input(client, "high", "netcfg/wireless_wpa"); ret = debconf_go(client); if (ret == 30) return GO_BACK; debconf_get(client, "netcfg/wireless_wpa"); interface->passphrase = strdup(client->value); } return 0; }
int netcfg_wireless_set_wep (struct debconfclient * client, struct netcfg_interface *interface) { wireless_config wconf; char* rv = NULL; int ret, keylen, err = 0; unsigned char buf [IW_ENCODING_TOKEN_MAX + 1]; struct iwreq wrq; iw_get_basic_config (wfd, interface->name, &wconf); debconf_subst(client, "netcfg/wireless_wep", "iface", interface->name); debconf_input (client, "high", "netcfg/wireless_wep"); ret = debconf_go(client); if (ret == CMD_GOBACK) return GO_BACK; debconf_get(client, "netcfg/wireless_wep"); rv = client->value; if (empty_str(rv)) { unset_wep_key (interface->name); if (interface->wepkey != NULL) { free(interface->wepkey); interface->wepkey = NULL; } return 0; } while ((keylen = iw_in_key (rv, buf)) == -1) { debconf_subst(client, "netcfg/invalid_wep", "wepkey", rv); debconf_input(client, "critical", "netcfg/invalid_wep"); debconf_go(client); debconf_input (client, "high", "netcfg/wireless_wep"); ret = debconf_go(client); if (ret == CMD_GOBACK) return GO_BACK; debconf_get(client, "netcfg/wireless_wep"); rv = client->value; } /* Now rv is safe to store since it parsed fine */ interface->wepkey = strdup(rv); wrq.u.data.pointer = buf; wrq.u.data.flags = 0; wrq.u.data.length = keylen; if ((err = iw_set_ext(skfd, interface->name, SIOCSIWENCODE, &wrq)) < 0) { di_warning("setting WEP key on %s failed with code %d", interface->name, err); return -1; } return 0; }
static int choose_country(void) { if (country) free(country); country = NULL; #if defined (WITH_FTP_MANUAL) assert(protocol != NULL); if (strcasecmp(protocol,"ftp") == 0) return 0; #endif debconf_get(debconf, DEBCONF_BASE "country"); if (! strlen(debconf->value)) { /* Not set yet. Seed with a default value. */ if ((debconf_get(debconf, "debian-installer/country") == 0) && (debconf->value != NULL) ) { country = strdup (debconf->value); debconf_set(debconf, DEBCONF_BASE "country", country); } } else { country = debconf->value; } /* Ensure 'country' is set to something. */ if (country == NULL || *country == 0) { country = "GB"; } char *countries; countries = add_protocol("countries"); if (has_mirror(country)) { const char *default_country = MANUAL_ENTRY; /* TODO: duplicates much of mirrors_in and has_mirror, since * those don't let us get the country at the moment */ if (strcmp(country, MANUAL_ENTRY) != 0 && strcmp(country, MANUAL_ENTRY_OLD) != 0) { int i = 0; struct mirror_t *mirrors = mirror_list(); for (i = 0; mirrors[i].country != NULL; i++) { if (strcmp(mirrors[i].country, country) == 0 || mirrors[i].wildcard) { default_country = mirrors[i].country; break; } } } debconf_set(debconf, countries, default_country); debconf_fget(debconf, DEBCONF_BASE "country", "seen"); debconf_fset(debconf, countries, "seen", debconf->value); } debconf_input(debconf, base_on_cd ? "medium" : "high", countries); free (countries); return 0; }
/* Check if the mirror carries the architecture that's being installed. */ int check_arch (void) { char *command; FILE *f = NULL; char *hostname, *directory, *suite = NULL; int valid = 0; hostname = add_protocol("hostname"); debconf_get(debconf, hostname); free(hostname); hostname = strdup(debconf->value); directory = add_protocol("directory"); debconf_get(debconf, directory); free(directory); directory = strdup(debconf->value); /* As suite has been determined previously, this should not fail */ debconf_get(debconf, DEBCONF_BASE "suite"); if (strlen(debconf->value) > 0) { suite = strdup(debconf->value); asprintf(&command, "wget -q %s://%s%s/dists/%s/main/binary-%s/Release -O - | grep Architecture", protocol, hostname, directory, suite, ARCH_TEXT); di_log(DI_LOG_LEVEL_DEBUG, "command: %s", command); f = popen(command, "r"); free(command); if (f != NULL) { char buf[SUITE_LENGTH]; if (fgets(buf, SUITE_LENGTH - 1, f)) if (strlen(buf) > 1) valid = 1; } pclose(f); } free(hostname); free(directory); if (suite) free(suite); if (valid) { return 0; } else { di_log(DI_LOG_LEVEL_DEBUG, "Architecture not supported by selected mirror"); debconf_input(debconf, "critical", DEBCONF_BASE "noarch"); if (debconf_go(debconf) == 30) exit(10); /* back up to menu */ else return 1; /* back to beginning of questions */ } }
/* Get the codename for the selected suite. */ int get_codename (void) { char *command; FILE *f = NULL; char *hostname, *directory, *suite = NULL; int ret = 1; hostname = add_protocol("hostname"); debconf_get(debconf, hostname); free(hostname); hostname = strdup(debconf->value); directory = add_protocol("directory"); debconf_get(debconf, directory); free(directory); directory = strdup(debconf->value); /* As suite has been determined previously, this should not fail */ debconf_get(debconf, DEBCONF_BASE "suite"); if (strlen(debconf->value) > 0) { suite = strdup(debconf->value); asprintf(&command, "wget -q %s://%s%s/dists/%s/Release -O - | grep ^Codename: | cut -d' ' -f 2", protocol, hostname, directory, suite); di_log(DI_LOG_LEVEL_DEBUG, "command: %s", command); f = popen(command, "r"); free(command); if (f != NULL) { char buf[SUITE_LENGTH]; if (fgets(buf, SUITE_LENGTH - 1, f)) { if (buf[strlen(buf) - 1] == '\n') buf[strlen(buf) - 1] = '\0'; debconf_set(debconf, DEBCONF_BASE "codename", buf); di_log(DI_LOG_LEVEL_INFO, "codename set to: %s", buf); ret = 0; } } pclose(f); } free(hostname); free(directory); if (suite) free(suite); if (ret != 0) di_log(DI_LOG_LEVEL_ERROR, "Error getting codename"); return ret; }
static int set_proxy(void) { char *px = add_protocol("proxy"); char *proxy_var; asprintf(&proxy_var, "%s_proxy", protocol); debconf_get(debconf, px); if (debconf->value != NULL && strlen(debconf->value)) { if (strchr(debconf->value, ':')) setenv(proxy_var, debconf->value, 1); else { char *proxy_value; asprintf(&proxy_value, "http://%s", debconf->value); setenv(proxy_var, proxy_value, 1); free(proxy_value); } } else { unsetenv(proxy_var); } free(proxy_var); free(px); return 0; }
void test1(struct debconfclient *client) { /* Showing the question the first time. */ debconf_reset(client, "foo/bar"); /* ask every time */ debconf_input(client, "low", "foo/bar"); debconf_go(client); debconf_get(client, "foo/bar"); /* Something with multiple choise. */ debconf_reset(client, "foo/choice"); debconf_subst(client, "foo/choice", "choices", "Whatever, Something more"); debconf_input(client, "high", "foo/choice"); debconf_go(client); debconf_get(client, "foo/choice"); and_again: /* Setting the value for foo/bar. */ debconf_set(client, "foo/bar", "stuff"); debconf_input(client, "low", "foo/bar"); debconf_go(client); debconf_get(client, "foo/bar"); /* Asking a boolean question. */ debconf_reset(client, "foo/my_question"); debconf_input(client, "high", "foo/my_question"); debconf_go(client); debconf_get(client, "foo/my_question"); /* Playing with Go Back button. */ debconf_capb(client, "backup"); debconf_reset(client, "foo/bar"); /* ask every time */ debconf_input(client, "high", "foo/bar"); int ret = debconf_go(client); if (ret == 30) { goto and_again; } debconf_get(client, "foo/bar"); }
int test2(struct debconfclient *client) { debconf_input(client, "high", "netcfg/base_system_config"); debconf_go(client); debconf_get(client, "netcfg/base_system_config"); return 0; }
static int fixup(void) { if (!do_mount_manual) return 0; debconf_get(debconf,"partconf/mountpoint-manual"); free(curr_part->op.mountpoint); curr_part->op.mountpoint = strdup(debconf->value); return 0; }
/* Returns the full path of the retriever command, either as set with * set_retriever or as stored in the debconf database. */ char *get_retriever(void) { if (! retriever_command) { debconf_get(debconf, DEFAULT_RETRIEVER_VAR); set_retriever(debconf->value, 0); if (get_lowmem_level() == 0) { retriever_usecached = 1; } } return retriever_command; }
void test2(struct debconfclient *client) { /* Something with multiple choise. */ debconf_reset(client, "foo/other_choice"); debconf_subst(client, "foo/other_choice", "choices", ""); debconf_input(client, "high", "foo/other_choice"); debconf_go(client); debconf_get(client, "foo/other_choice"); }
static int choose_country(void) { if (country) free(country); country = NULL; #if defined (WITH_FTP_MANUAL) assert(protocol != NULL); if (strcasecmp(protocol,"ftp") == 0) return 0; #endif debconf_get(debconf, DEBCONF_BASE "country"); if (! strlen(debconf->value)) { /* Not set yet. Seed with a default value. */ if ((debconf_get(debconf, "debian-installer/country") == 0) && (debconf->value != NULL) ) { country = strdup (debconf->value); debconf_set(debconf, DEBCONF_BASE "country", country); } } else { country = debconf->value; } /* Ensure 'country' is set to something. */ if (country == NULL || *country == 0) { country = "GB"; } char *countries; countries = add_protocol("countries"); if (has_mirror(country)) { debconf_set(debconf, countries, country); debconf_fget(debconf, DEBCONF_BASE "country", "seen"); debconf_fset(debconf, countries, "seen", debconf->value); } debconf_input(debconf, base_on_cd ? "medium" : "high", countries); free (countries); return 0; }
static int choose_mirror(void) { char *list; char *countryarchive; int i; debconf_get(debconf, DEBCONF_BASE "country"); #ifndef WITH_FTP_MANUAL manual_entry = ! strcmp(debconf->value, MANUAL_ENTRY) || ! strcmp(debconf->value, MANUAL_ENTRY_OLD); #else if (! strcasecmp(protocol,"ftp") == 0) manual_entry = ! strcmp(debconf->value, MANUAL_ENTRY) || ! strcmp(debconf->value, MANUAL_ENTRY_OLD); else manual_entry = 1; #endif if (! manual_entry) { char *mir = add_protocol("mirror"); countryarchive=malloc(strlen(country) + strlen(".archive.ubuntu.com") + 1); for (i = 0; country[i]; ++i) countryarchive[i] = tolower((unsigned char) country[i]); strcpy(countryarchive + i, ".archive.ubuntu.com"); /* Prompt for mirror in selected country. */ list=debconf_list(mirrors_in(country)); debconf_subst(debconf, mir, "mirrors", list); if (debconf_fget(debconf, mir, "seen") != 0 || strcmp(debconf->value, "true") != 0) if (mirror_root(countryarchive)) debconf_set(debconf, mir, countryarchive); free(list); free(countryarchive); debconf_input(debconf, base_on_cd ? "medium" : "high", mir); free(mir); } else { char *host = add_protocol("hostname"); char *dir = add_protocol("directory"); /* Manual entry. */ debconf_input(debconf, "critical", host); debconf_input(debconf, "critical", dir); free(host); free(dir); } return 0; }
static int get_protocol(void) { #if defined (WITH_HTTP) && (defined (WITH_FTP) || defined (WITH_FTP_MANUAL)) debconf_get(debconf, DEBCONF_BASE "protocol"); protocol = strdup(debconf->value); #else #ifdef WITH_HTTP debconf_set(debconf, DEBCONF_BASE "protocol", "http"); protocol = "http"; #endif #ifdef WITH_FTP debconf_set(debconf, DEBCONF_BASE "protocol", "ftp"); protocol = "ftp"; #endif #endif /* WITH_HTTP && WITH_FTP */ return 0; }
static int choose_proxy(void) { char *px = add_protocol("proxy"); /* This is a nasty way to check whether we ought to have a network * connection; if we don't, it isn't worthwhile to ask for a proxy. * We should really change netcfg to write out a flag somewhere. */ if (debconf_get(debconf, "netcfg/dhcp_options") == 0 && debconf->value != NULL && strncmp(debconf->value, "Do not configure", strlen("Do not configure")) == 0) { debconf_input(debconf, "low", px); } else { debconf_input(debconf, "high", px); } free(px); return 0; }
int wireless_security_type (struct debconfclient *client, const char *if_name) { debconf_subst(client, "netcfg/wireless_security_type", "iface", if_name); debconf_input(client, "high", "netcfg/wireless_security_type"); if (debconf_go(client) == CMD_GOBACK) return GO_BACK; debconf_get(client, "netcfg/wireless_security_type"); if (!strcmp(client->value, "wep/open")) return REPLY_WEP; else return REPLY_WPA; }
static int set_country(void) { char *countries; #if defined (WITH_FTP_MANUAL) assert(protocol != NULL); if (strcasecmp(protocol,"ftp") == 0) return 0; #endif countries = add_protocol("countries"); debconf_get(debconf, countries); country = strdup(debconf->value); debconf_set(debconf, DEBCONF_BASE "country", country); free (countries); return 0; }
static int mountpoint_manual(void) { if (curr_part->op.filesystem != NULL && strcmp(curr_part->op.filesystem, "swap") == 0) return 0; do_mount_manual = 0; debconf_get(debconf, "partconf/mountpoint"); if (strcmp(debconf->value, "Don't mount it") == 0) { free(curr_part->op.mountpoint); curr_part->op.mountpoint = NULL; } else if (strcmp(debconf->value, "Enter manually") == 0) { debconf_subst(debconf, "partconf/mountpoint-manual", "PARTITION", curr_part->path); debconf_input(debconf, "critical", "partconf/mountpoint-manual"); do_mount_manual = 1; } else { //printf("Setting mountpoint to %s\n", debconf->value); free(curr_part->op.mountpoint); curr_part->op.mountpoint = strdup(debconf->value); } return 0; }
response_t netcfg_get_method(struct debconfclient *client) { int iret; iret = debconf_input(client, "medium", "netcfg/use_autoconfig"); if (debconf_go(client) == CMD_GOBACK) return GO_BACK; debconf_get(client, "netcfg/use_autoconfig"); if (strcmp(client->value, "true") == 0) netcfg_method = DHCP; else netcfg_method = STATIC; if (iret == CMD_INPUTINVISIBLE) return NOT_ASKED; return 0; }
int test1(struct debconfclient *client) { int rv = 0; debconf_capb(client, ""); debconf_subst(client, "netcfg/write_wireless_config", "iface", "eht1"); debconf_subst(client, "netcfg/write_wireless_config", "interfaces_file", "some_file"); debconf_input(client, "medium", "netcfg/write_wireless_config"); debconf_go(client); debconf_get(client, "netcfg/write_wireless_config"); fprintf(stderr, "%s\n", client->value); if (!empty_str(client->value) && strcmp(client->value, "true") == 0) { rv = 1; } debconf_capb(client, "backup"); return rv; }
static int mountpoint(void) { int i; debconf_get(debconf, curr_q); if (strcmp(debconf->value, "Leave the file system intact") == 0) { free(curr_part->op.filesystem); curr_part->op.filesystem = NULL; if (curr_part->fstype != NULL && strcmp(curr_part->fstype, "swap") == 0) return 0; } else if (strcmp(debconf->value, "Create swap space") == 0) { free(curr_part->op.filesystem); curr_part->op.filesystem = strdup("swap"); // special case free(curr_part->op.mountpoint); curr_part->op.mountpoint = NULL; return 0; } else { char *tmp = strdup(debconf->value); for (i = 0; i < fs_count; i++) { if (strcmp(tmp, fs_to_choice(filesystems[i])) == 0) break; } free(tmp); if (i == fs_count) return -1; free(curr_part->op.filesystem); curr_part->op.filesystem = strdup(filesystems[i]); } if (curr_part->op.filesystem == NULL || strcmp(curr_part->op.filesystem, "swap") != 0) { // TODO: default to current mount point, if any debconf_subst(debconf, "partconf/mountpoint", "PARTITION", curr_part->path); debconf_input(debconf, "critical", "partconf/mountpoint"); } return 0; }
/* * Get the default suite (can be a codename) to use; this is either a * preseeded value or a value set at build time. */ static char *get_default_suite(void) { char *suite = NULL; FILE *f = NULL; char buf[SUITE_LENGTH]; debconf_get(debconf, DEBCONF_BASE "suite"); if (strlen(debconf->value) > 0) { /* Use preseeded or previously selected value. */ suite = strdup(debconf->value); } else { /* Check for default suite/codename set at build time. */ f = fopen("/etc/default-release", "r"); if (f != NULL) { if (fgets(buf, SUITE_LENGTH - 1, f)) { if (buf[strlen(buf) - 1] == '\n') buf[strlen(buf) - 1] = '\0'; suite = strdup(buf); } fclose(f); } } return suite; }
static int filesystem(void) { int i; char *partname; debconf_get(debconf, "partconf/partitions"); if (strcmp(debconf->value, "Finish") == 0) { if (!sanity_checks()) return 1; // will back up finish(); } if (strcmp(debconf->value, "Abort") == 0) return -1; partname = strdup(debconf->value); curr_part = NULL; for (i = 0; i < part_count; i++) { //fprintf(stderr, "pname='%s', pdesc='%s'\n", partname, parts[i]->description); if (streqcomma(parts[i]->description, partname)) { // if (strstr(partname, parts[i]->description) == partname) { curr_part = parts[i]; break; } } if (curr_part == NULL) return -1; if (curr_part->fstype != NULL) { curr_q = "partconf/existing-filesystem"; debconf_subst(debconf, curr_q, "FSTYPE", curr_part->fstype); debconf_set(debconf, curr_q, "Leave the file system intact"); } else curr_q = "partconf/create-filesystem"; debconf_subst(debconf, curr_q, "FSCHOICES", fschoices); debconf_subst(debconf, curr_q, "PARTITION", curr_part->path); debconf_input(debconf, "critical", curr_q); return 0; }
static int validate_mirror(void) { char *mir; char *host; char *dir; int valid; mir = add_protocol("mirror"); host = add_protocol("hostname"); dir = add_protocol("directory"); if (! manual_entry) { char *mirror; /* * Copy information about the selected * mirror into mirror/{protocol}/{hostname,directory}, * which is the standard location other * tools can look at. */ debconf_get(debconf, mir); mirror = strdup(debconf->value); debconf_set(debconf, host, mirror); debconf_set(debconf, dir, mirror_root(mirror)); free(mirror); if (base_on_cd) { /* We have the base system on the CD, so instead of * trying to contact the mirror (which might take * some time to time out if there's no network * connection), let's just assume that the CD will * be sufficient to get a basic system up, setting * suite to PREFERRED_DISTRIBUTION if unset and * codename = suite. Note that this is an * Ubuntu-specific change since (a) Debian netinst * CDs etc. may not be able to install a complete * system from the network and (b) codename != suite * in Debian. * * We only do this for mirrors in our mirror list, * since we assume that those have a good chance of * not being typoed. For manually-entered mirrors, * we still do full mirror validation. */ di_log(DI_LOG_LEVEL_INFO, "base system installable from CD; skipping mirror check"); debconf_get(debconf, DEBCONF_BASE "suite"); if (!*debconf->value) { di_log(DI_LOG_LEVEL_INFO, "falling back to suite %s", PREFERRED_DISTRIBUTION); debconf_set(debconf, DEBCONF_BASE "suite", PREFERRED_DISTRIBUTION); } debconf_get(debconf, DEBCONF_BASE "suite"); di_log(DI_LOG_LEVEL_INFO, "falling back to codename %s", debconf->value); debconf_set(debconf, DEBCONF_BASE "codename", debconf->value); exit(0); } valid = find_suite(); } else { /* check to see if the entered data is basically ok */ int ok = 1; debconf_get(debconf, host); if (debconf->value == NULL || strcmp(debconf->value, "") == 0 || strchr(debconf->value, '/') != NULL) { ok = 0; } debconf_get(debconf, dir); if (debconf->value == NULL || strcmp(debconf->value, "") == 0) { ok = 0; } if (ok) { valid = find_suite(); } else { valid = 0; } } free(mir); free(host); free(dir); if (valid) { return 0; } else { debconf_input(debconf, "critical", DEBCONF_BASE "bad"); if (debconf_go(debconf) == 30) exit(10); /* back up to menu */ else return 1; /* back to beginning of questions */ } }
static int sanity_checks(void) { int i, j, ok; static char *bad_mounts[] = { "/proc", "/dev", "/etc", NULL }; // Check for root file system if (!check_proc_mounts("")) { ok = 0; for (i = 0; i < part_count; i++) { if (parts[i]->op.mountpoint == NULL) continue; if (strcmp(parts[i]->op.mountpoint, "/") == 0) { ok = 1; break; } } if (!ok) { debconf_input(debconf,"critical", "partconf/sanity-no-root"); debconf_go(debconf); return 0; } } // Check for bad mount points (/proc, /dev, /etc) ok = 1; for (i = 0; i < part_count; i++) { if (parts[i]->op.mountpoint == NULL) continue; for (j = 0; bad_mounts[j] != NULL; j++) { if (strcmp(parts[i]->op.mountpoint, bad_mounts[j]) == 0) { debconf_subst(debconf, "partconf/sanity-bad-mount", "MOUNT", parts[i]->op.mountpoint); debconf_input(debconf, "critical", "partconf/sanity-bad-mount"); debconf_go(debconf); ok = 0; break; } } } if (!ok) return 0; // Check for double mounts ok = 1; for (i = 0; i < part_count; i++) { if (parts[i]->op.mountpoint == NULL) continue; if (check_proc_mounts(parts[i]->op.mountpoint)) { debconf_subst(debconf, "partconf/sanity-double-mount", "MOUNT", parts[i]->op.mountpoint); debconf_input(debconf, "critical", "partconf/sanity-double-mount"); debconf_go(debconf); ok = 0; } else for (j = i+1; j < part_count; j++) { if (parts[j]->op.mountpoint == NULL) continue; if (strcmp(parts[i]->op.mountpoint, parts[j]->op.mountpoint) == 0) { debconf_subst(debconf,"partconf/sanity-double-mount", "MOUNT", parts[i]->op.mountpoint); debconf_input(debconf, "critical", "partconf/sanity-double-mount"); debconf_go(debconf); ok = 0; break; } } } if (!ok) return 0; if (will_mkfs()) { // Confirm // XXX Can we build a sane substitution string? Would be nice to say // XXX something like "Partitions 1, 3 and 7 on IDE3 master", but this // XXX is probably hard, especially for i18n. :-( If multi-line // XXX substitutions worked, we could just list the partitions. debconf_set(debconf, "partconf/confirm", "false"); debconf_input(debconf, "critical", "partconf/confirm"); if (debconf_go(debconf) == 30) return 0; debconf_get(debconf, "partconf/confirm"); if (strcmp(debconf->value, "false") == 0) return 0; } return 1; }
int main(void) { int i, state = 0, ret; int (*states[])() = { partition_menu, filesystem, mountpoint, mountpoint_manual, fixup, // never does an INPUT, just handles the manual mountpoint result NULL }; /* FIXME: How can we tell which file system modules to load? */ char *file_system_modules[] = {"ext2", "ext3", "reiserfs", "jfs", "xfs", NULL}; debconf = debconfclient_new(); debconf_capb(debconf, "backup"); ped_exception_set_handler(my_exception_handler); for (i = 0; file_system_modules[i]; i++) modprobe(file_system_modules[i]); if (check_proc_mounts("")) { // Chicken out if /target is already mounted debconf_set(debconf,"partconf/already-mounted", "no"); debconf_input(debconf, "critical", "partconf/already-mounted"); debconf_go(debconf); debconf_get(debconf,"partconf/already-mounted"); if (strcmp(debconf->value, "false") == 0) return 0; } if (!umount_target()) { debconf_input(debconf, "critical", "partconf/umount-failed"); debconf_go(debconf); return 1; } if ((part_count = get_all_partitions(parts, MAX_PARTS, false, 0)) <= 0) { debconf_input(debconf, "critical", "partconf/no-partitions"); debconf_go(debconf); return 1; } if (get_all_filesystems() <= 0) { debconf_input(debconf, "critical", "partconf/no-filesystems"); debconf_go(debconf); return 1; } fschoices = build_fs_choices(); while (state >= 0) { ret = states[state](); if (ret < 0) return 10; else if (ret == 0 && debconf_go(debconf) == 0) state++; else state--; if (states[state] == NULL) state = 0; } return ret; }
int main(int argc, char *argv[]) { int num_interfaces = 0; enum { BACKUP, GET_INTERFACE, GET_HOSTNAME_ONLY, GET_METHOD, GET_DHCP, GET_STATIC, WCONFIG, WCONFIG_ESSID, WCONFIG_SECURITY_TYPE, WCONFIG_WEP, WCONFIG_WPA, START_WPA, QUIT } state = GET_INTERFACE; static struct debconfclient *client; static int requested_wireless_tools = 0; char **ifaces; char *defiface = NULL, *defwireless = NULL; response_t res; struct netcfg_interface interface; #ifdef NM struct nm_config_info nmconf; #endif /* initialize libd-i */ di_system_init("netcfg"); netcfg_interface_init(&interface); if (strcmp(basename(argv[0]), "ptom") != 0) di_info("Starting netcfg v.%s", NETCFG_VERSION); parse_args (argc, argv); reap_old_files (); open_sockets(); /* initialize debconf */ client = debconfclient_new(); debconf_capb(client, "backup"); /* Check to see if netcfg should be run at all */ debconf_get(client, "netcfg/enable"); if (!strcmp(client->value, "false")) { netcfg_get_hostname(client, "netcfg/get_hostname", hostname, 0); netcfg_write_common("", hostname, NULL); return 0; } /* always always always default back to autoconfig, unless you've specified * disable_autoconfig on the command line. */ debconf_get(client, "netcfg/disable_autoconfig"); if (!strcmp(client->value, "true")) debconf_set(client, "netcfg/use_autoconfig", "false"); else debconf_set(client, "netcfg/use_autoconfig", "true"); /* also support disable_dhcp for compatibility */ debconf_get(client, "netcfg/disable_dhcp"); if (!strcmp(client->value, "true")) debconf_set(client, "netcfg/use_autoconfig", "false"); for (;;) { switch(state) { case BACKUP: return RETURN_TO_MAIN; case GET_INTERFACE: /* If we have returned from outside of netcfg and want to * reconfigure networking, check to see if wpasupplicant is * running, and kill it if it is. If left running when * the interfaces are taken up and down, it appears to * leave it in an inconsistant state */ kill_wpa_supplicant(); /* Choose a default by looking for link */ if (get_all_ifs(1, &ifaces) > 1) { while (*ifaces) { struct netcfg_interface link_interface; if (check_kill_switch(*ifaces)) { debconf_subst(client, "netcfg/kill_switch_enabled", "iface", *ifaces); debconf_input(client, "high", "netcfg/kill_switch_enabled"); if (debconf_go(client) == CMD_GOBACK) { state = BACKUP; break; } /* Is it still enabled? */ if (check_kill_switch(*ifaces)) { ifaces++; continue; } } interface_up(*ifaces); netcfg_interface_init(&link_interface); link_interface.name = strdup(*ifaces); if (netcfg_detect_link (client, &link_interface) == 1) /* CONNECTED */ { /* CONNECTED */ di_info("found link on interface %s, making it the default.", *ifaces); defiface = strdup(*ifaces); free(link_interface.name); break; } else { #ifdef WIRELESS struct wireless_config wc; #endif /* WIRELESS */ di_info("found no link on interface %s.", *ifaces); #ifdef WIRELESS if (iw_get_basic_config(wfd, *ifaces, &wc) == 0) { wc.essid[0] = '\0'; wc.essid_on = 0; iw_set_basic_config(wfd, *ifaces, &wc); sleep(1); iw_get_basic_config(wfd, *ifaces, &wc); if (!empty_str(wc.essid)) { di_info("%s is associated with %s. Selecting as default", *ifaces, wc.essid); defiface = strdup(*ifaces); interface_down(*ifaces); break; } else { di_info("%s is not associated. Relegating to defwireless", *ifaces); if (defwireless != NULL) free (defwireless); defwireless = strdup(*ifaces); } } else di_info("%s is not a wireless interface. Continuing.", *ifaces); interface_down(*ifaces); #endif } free(link_interface.name); interface_down(*ifaces); ifaces++; } } if (state == BACKUP) break; if (!defiface && defwireless) defiface = defwireless; if(netcfg_get_interface(client, &(interface.name), &num_interfaces, defiface)) state = BACKUP; else if (! interface.name || ! num_interfaces) state = GET_HOSTNAME_ONLY; else { if (is_wireless_iface (interface.name)) state = WCONFIG; else state = GET_METHOD; } break; case GET_HOSTNAME_ONLY: if(netcfg_get_hostname(client, "netcfg/get_hostname", hostname, 0)) state = BACKUP; else { netcfg_write_common("", hostname, NULL); state = QUIT; } break; case GET_METHOD: if ((res = netcfg_get_method(client)) == GO_BACK) state = (num_interfaces == 1) ? BACKUP : GET_INTERFACE; else { if (netcfg_method == DHCP) state = GET_DHCP; else state = GET_STATIC; } break; case GET_DHCP: switch (netcfg_activate_dhcp(client, &interface)) { case 0: state = QUIT; break; case RETURN_TO_MAIN: /* * It doesn't make sense to go back to GET_METHOD because * the user has already been asked whether they want to * try an alternate method. */ state = (num_interfaces == 1) ? BACKUP : GET_INTERFACE; break; case CONFIGURE_MANUALLY: state = GET_STATIC; break; default: return 1; } break; case GET_STATIC: { int ret; /* Misnomer - this should actually take care of activation */ if ((ret = netcfg_get_static(client, &interface)) == RETURN_TO_MAIN) state = GET_INTERFACE; else if (ret) state = GET_METHOD; else state = QUIT; break; } case WCONFIG: if (requested_wireless_tools == 0) { di_exec_shell_log("apt-install iw wireless-tools"); requested_wireless_tools = 1; } state = WCONFIG_ESSID; break; case WCONFIG_ESSID: if (netcfg_wireless_set_essid(client, &interface) == GO_BACK) state = BACKUP; else { init_wpa_supplicant_support(&interface); if (interface.wpa_supplicant_status == WPA_UNAVAIL) state = WCONFIG_WEP; else state = WCONFIG_SECURITY_TYPE; } break; case WCONFIG_SECURITY_TYPE: { int ret; ret = wireless_security_type(client, interface.name); if (ret == GO_BACK) state = WCONFIG_ESSID; else if (ret == REPLY_WPA) { state = WCONFIG_WPA; interface.wifi_security = REPLY_WPA; } else { state = WCONFIG_WEP; interface.wifi_security = REPLY_WEP; } break; } case WCONFIG_WEP: if (netcfg_wireless_set_wep(client, &interface) == GO_BACK) if (interface.wpa_supplicant_status == WPA_UNAVAIL) state = WCONFIG_ESSID; else state = WCONFIG_SECURITY_TYPE; else state = GET_METHOD; break; case WCONFIG_WPA: if (interface.wpa_supplicant_status == WPA_OK) { di_exec_shell_log("apt-install wpasupplicant"); interface.wpa_supplicant_status = WPA_QUEUED; } if (netcfg_set_passphrase(client, &interface) == GO_BACK) state = WCONFIG_SECURITY_TYPE; else state = START_WPA; break; case START_WPA: if (wpa_supplicant_start(client, &interface) == GO_BACK) state = WCONFIG_ESSID; else state = GET_METHOD; break; case QUIT: #ifdef NM if (num_interfaces > 0) { nm_get_configuration(&interface, &nmconf); nm_write_configuration(nmconf); } #endif netcfg_update_entropy(); return 0; } } }
int netcfg_wireless_show_essids(struct debconfclient *client, struct netcfg_interface *interface) { wireless_scan_head network_list; wireless_config wconf; char *buffer; int essid_list_len = 1; iw_get_basic_config (wfd, interface->name, &wconf); interface_up(interface->name); if (iw_scan(wfd, interface->name, iw_get_kernel_we_version(), &network_list) >= 0 ) { wireless_scan *network; di_info("Scan of wireless interface %s succeeded.", interface->name); /* Determine the actual length of the buffer. */ for (network = network_list.result; network; network = network->next) { if (!exists_in_network_list(network_list, network)) { essid_list_len += (strlen(network->b.essid) + 2); } } /* Buffer initialization. */ buffer = malloc(essid_list_len * sizeof(char)); if (buffer == NULL) { /* Error in memory allocation. */ di_warning("Unable to allocate memory for network list buffer."); return ENTER_MANUALLY; } strcpy(buffer, ""); /* Create list of available ESSIDs. */ for (network = network_list.result; network; network = network->next) { if (!exists_in_network_list(network_list, network)) { strcat(buffer, network->b.essid); strcat(buffer, ", "); } } /* Asking the user. */ debconf_capb(client, "backup"); debconf_subst(client, "netcfg/wireless_show_essids", "essid_list", buffer); debconf_fset(client, "netcfg/wireless_show_essids", "seen", "false"); debconf_input(client, "high", "netcfg/wireless_show_essids"); if (debconf_go(client) == CMD_GOBACK) { debconf_fset(client, "netcfg/wireless_show_essids", "seen", "false"); free_network_list(&network_list.result); free(buffer); return GO_BACK; } debconf_get(client, "netcfg/wireless_show_essids"); /* User wants to enter an ESSID manually. */ if (strcmp(client->value, "manual") == 0) { free_network_list(&network_list.result); free(buffer); return ENTER_MANUALLY; } /* User has chosen a network from the list, need to find which one and * get its cofiguration. */ for (network = network_list.result; network; network = network->next) { if (strcmp(network->b.essid, client->value) == 0) { wconf = network->b; interface->essid = strdup(network->b.essid); break; } } /* Free the network list. */ free_network_list(&network_list.result); free(buffer); } else { /* Go directly to choosing manually, use the wireless_essid_again * question. */ if (netcfg_wireless_choose_essid_manually(client, interface, "netcfg/wireless_essid_again") == GO_BACK) { return GO_BACK; } return 0; } iw_set_basic_config(wfd, interface->name, &wconf); interface_down(interface->name); di_info("Network chosen: %s. Proceeding to connect.", interface->essid); return 0; }
/* * Using the current debconf settings for a mirror, figure out which suite * to use from the mirror and set mirror/suite. * * This is accomplished by downloading the Release file from the mirror. * Suite selection tries each suite in turn, and stops at the first one that * seems usable. * * If no Release file is found, returns false. That probably means the * mirror is broken or unreachable. */ int find_suite (void) { char *command; FILE *f = NULL; char *hostname, *directory; int nbr_suites = sizeof(suites)/SUITE_LENGTH; int i; int ret = 0; char buf[SUITE_LENGTH]; if (show_progress) { debconf_progress_start(debconf, 0, 1, DEBCONF_BASE "checking_title"); debconf_progress_info(debconf, DEBCONF_BASE "checking_download"); } hostname = add_protocol("hostname"); debconf_get(debconf, hostname); free(hostname); hostname = strdup(debconf->value); directory = add_protocol("directory"); debconf_get(debconf, directory); free(directory); directory = strdup(debconf->value); /* Try each suite in turn until one is found that works. */ for (i=0; i <= nbr_suites && ! ret; i++) { char *suite; if (i == 0) { /* First check for a preseeded suite. */ debconf_get(debconf, DEBCONF_BASE "suite"); if (strlen(debconf->value) > 0) { suite = strdup(debconf->value); } else { /* Read this file to find the default suite * to use. */ f = fopen("/etc/default-release", "r"); if (f != NULL) { if (fgets(buf, SUITE_LENGTH - 1, f)) { if (buf[strlen(buf) - 1] == '\n') buf[strlen(buf) - 1] = '\0'; suite = strdup(buf); fclose(f); } else { fclose(f); continue; } } else { continue; } } } else { suite = strdup(suites[i - 1]); } asprintf(&command, "wget -q %s://%s%s/dists/%s/Release -O - | grep ^Suite: | cut -d' ' -f 2", protocol, hostname, directory, suite); di_log(DI_LOG_LEVEL_DEBUG, "command: %s", command); f = popen(command, "r"); free(command); if (f != NULL) { if (fgets(buf, SUITE_LENGTH - 1, f)) { if (buf[strlen(buf) - 1] == '\n') buf[strlen(buf) - 1] = '\0'; debconf_set(debconf, DEBCONF_BASE "suite", buf); ret = 1; } } pclose(f); free(suite); } free(hostname); free(directory); if (show_progress) { debconf_progress_step(debconf, 1); debconf_progress_stop(debconf); } return ret; }
int netcfg_wireless_choose_essid_manually(struct debconfclient *client, struct netcfg_interface *interface, char *question) { wireless_config wconf; iw_get_basic_config (wfd, interface->name, &wconf); debconf_subst(client, question, "iface", interface->name); debconf_subst(client, "netcfg/wireless_adhoc_managed", "iface", interface->name); if (debconf_go(client) == CMD_GOBACK) { debconf_fset(client, question, "seen", "false"); return GO_BACK; } debconf_get(client, "netcfg/wireless_adhoc_managed"); if (!strcmp(client->value, "Ad-hoc network (Peer to peer)")) { interface->mode = ADHOC; } wconf.has_mode = 1; wconf.mode = interface->mode; get_essid: debconf_input(client, "high", question); if (debconf_go(client) == CMD_GOBACK) { return GO_BACK; } debconf_get(client, question); if (client->value && strlen(client->value) > IW_ESSID_MAX_SIZE) { char max_len_string[5]; sprintf(max_len_string, "%d", IW_ESSID_MAX_SIZE); debconf_capb(client, ""); debconf_subst(client, "netcfg/invalid_essid", "essid", client->value); debconf_subst(client, "netcfg/invalid_essid", "max_essid_len", max_len_string); debconf_input(client, "critical", "netcfg/invalid_essid"); debconf_go(client); debconf_fset(client, question, "seen", "false"); debconf_capb(client, "backup"); goto get_essid; } interface->essid = strdup(client->value); memset(wconf.essid, 0, IW_ESSID_MAX_SIZE + 1); snprintf(wconf.essid, IW_ESSID_MAX_SIZE + 1, "%s", interface->essid); wconf.has_essid = 1; wconf.essid_on = 1; iw_set_basic_config(wfd, interface->name, &wconf); di_info("Network chosen: %s. Proceeding to connect.", interface->essid); return 0; }