Esempio n. 1
0
void advanced_quit (void)
{

	if (!USE_PRIMENET) {
		outputLongLine (MANUAL_QUIT);
		if (askYesNo ('N')) {
			writeResults ("Quitting GIMPS.\n");
//bug - either delete file, or delete all work_units and write the file.
//bug			IniDeleteAllLines (WORKTODO_FILE);
			stop_workers_for_escape ();
		}
	} else {
		int	res;
		outputLongLine (PRIMENET_QUIT);
		res = askYesNoCancel ('C');
		if (res == 0) {
			OutputBoth (MAIN_THREAD_NUM, "Quitting GIMPS after current work completes.\n");
			IniWriteInt (INI_FILE, "NoMoreWork", 1);
			askOK ();
		}
		if (res == 1) {
			OutputBoth (MAIN_THREAD_NUM, "Quitting GIMPS immediately.\n");
			spoolMessage (MSG_QUIT_GIMPS, NULL);
			askOK ();
		}
	}
}
Esempio n. 2
0
void advanced_manualcomm (void)
{
	int	m_manual_comm, m_comm_now, m_new_dates;

	m_manual_comm = MANUAL_COMM;
	m_comm_now = 1;
	m_new_dates = 0;

	m_manual_comm = !m_manual_comm;
	askYN ("Contact PrimeNet server automatically", &m_manual_comm);
	m_manual_comm = !m_manual_comm;
	askYN ("Contact PrimeNet server now", &m_comm_now);
	askYN ("Send new expected completion dates to server", &m_new_dates);

	if (askOkCancel ()) {
		if ((MANUAL_COMM && !m_manual_comm) ||
		    (!MANUAL_COMM && m_manual_comm)) {
			MANUAL_COMM = m_manual_comm;
			IniWriteInt (INI_FILE, "ManualComm", MANUAL_COMM);
			set_comm_timers ();
		}
		if (m_new_dates) UpdateEndDates ();
		if (m_comm_now) do_manual_comm_now ();
	}
}
Esempio n. 3
0
void test_welcome (void)
{
	int	m_join = 1;

/* Set global flag indicating startup is in progress.  This will delay */
/* starting any communication with the server until the user has confirmed */
/* he wants to use primenet and he has selected his work preferences. */
	
	STARTUP_IN_PROGRESS = 1;

	outputLongLine ("\nWelcome to GIMPS, the hunt for huge prime numbers.  You will be asked a few simple questions and then the program will contact the primenet server to get some work for your computer.  Good luck!\n");
	outputLongLine ("\nAttention OVERCLOCKERS!!  Mprime has gained a reputation as a useful stress testing tool for people that enjoy pushing their hardware to the limit.  You are more than welcome to use this software for that purpose.  Please select the stress testing choice below to avoid interfering with the PrimeNet server.  Use the Options/Torture Test menu choice for your stress tests.  Also, read the stress.txt file.\n");
	outputLongLine ("\nIf you want to both join GIMPS and run stress tests, then Join GIMPS and answer the questions.  After the server gets some work for you, stop mprime, then run mprime -m and choose Options/Torture Test.\n\n");
	askYN ("Join Gimps? (Y=Yes, N=Just stress testing)", &m_join);
	if (m_join) {
		STRESS_TESTER = 0;
		IniWriteInt (INI_FILE, "StressTester", 0);
		USE_PRIMENET = 1;
		IniWriteInt (INI_FILE, "UsePrimenet", 1);
		test_primenet ();
		if (USE_PRIMENET && STARTUP_IN_PROGRESS) options_cpu ();
		if (USE_PRIMENET && STARTUP_IN_PROGRESS) test_worker_threads ();
		if (USE_PRIMENET && STARTUP_IN_PROGRESS) {
			STARTUP_IN_PROGRESS = 0;
			set_comm_timers ();
			linuxContinue (NULL, ALL_WORKERS, FALSE);
		} else
			STARTUP_IN_PROGRESS = 0;
	} else {
		STRESS_TESTER = 1;
		IniWriteInt (INI_FILE, "StressTester", 1);
		USE_PRIMENET = 0;
		IniWriteInt (INI_FILE, "UsePrimenet", USE_PRIMENET = 0);
		STARTUP_IN_PROGRESS = 0;
		torture ();
	}
	main_menu ();
}
Esempio n. 4
0
void linuxContinue (
	char	*error_message,
	int	thread_num,		/* Specific worker to launch or */
					/* special value ALL_WORKERS */
	int	wait_flag)
{
#ifdef __linux__
#define PROCNAME	"/proc/%d/exe"
#endif
#ifdef __FreeBSD__
#define PROCNAME	"/proc/%d/file"
#endif
	pid_t	my_pid, running_pid;
	char	filename[30];
	int	fd;
	struct stat filedata;
	ino_t	inode1, inode2;

/* Compare this process' ID and the pid from the INI file */

	my_pid = getpid ();
	openIniFile (LOCALINI_FILE, 1);
	running_pid = IniGetInt (LOCALINI_FILE, "Pid", 0);
	if (running_pid == 0 || my_pid == running_pid) goto ok;

#if defined (__APPLE__) || defined (__HAIKU__)
	goto ok;
#elif defined (__OS2__)

        {
            USHORT handle1 = 0, handle2 = 0;
            unsigned char buf[0x2000];
            if( !DosQuerySysState(0x01, 0, 0, 0, (PCHAR)buf, 0x2000) ) {
                PQPROCESS p = ((PQTOPLEVEL)buf)->procdata;
                while(p && p->rectype == 1) {
                    if( p->pid == running_pid ) handle1 = p->hndmod;
                    if( p->pid == my_pid ) handle2 = p->hndmod;
                    p = (PQPROCESS)(p->threads + p->threadcnt);
                }
                if( handle1 != handle2 ) goto ok;
            }
        }

#else

/* See if the two pids are running the same executable */

	sprintf (filename, PROCNAME, my_pid);
	fd = _open (filename, _O_RDONLY);
	if (fd < 0) goto ok;
	fstat (fd, &filedata);
	inode1 = filedata.st_ino;
	_close (fd);
	sprintf (filename, PROCNAME, running_pid);
	fd = _open (filename, _O_RDONLY);
	if (fd < 0) goto ok;
	fstat (fd, &filedata);
	inode2 = filedata.st_ino;
	_close (fd);
	if (inode1 != inode2) goto ok;
#endif

/* The two pids are running the same executable, raise an error and return */

	if (error_message != NULL) printf ("%s", error_message);
	return;

/* All is OK, save our pid, run, then delete our pid */

ok:	IniWriteInt (LOCALINI_FILE, "Pid", my_pid);
	LaunchWorkerThreads (thread_num, wait_flag);
	if (wait_flag) IniWriteInt (LOCALINI_FILE, "Pid", 0);
}
Esempio n. 5
0
void torture (void)
{
	unsigned long m_thread, m_type, m_minfft, m_maxfft;
	unsigned long m_memory, m_timefft;
	unsigned long mem, blendmemory;

	m_thread = NUM_CPUS * CPU_HYPERTHREADS;
	mem = physical_memory ();
	if (mem >= 2000) {
		blendmemory = GetSuggestedMemory (1600);
	} else if (mem >= 500) {
		blendmemory = GetSuggestedMemory (mem - 256);
	} else if (mem >= 200) {
		blendmemory = GetSuggestedMemory (mem / 2);
	} else {
		blendmemory = 8;
	}
	m_timefft = 3;

	if (NUM_CPUS * CPU_HYPERTHREADS > 1)
		askNum ("Number of torture test threads to run", &m_thread,
			1, NUM_CPUS * CPU_HYPERTHREADS);

	outputLongLine ("Choose a type of torture test to run.\n  1 = Small FFTs (maximum heat and FPU stress, data fits in L2 cache, RAM not tested much).\n  2 = In-place large FFTs (maximum power consumption, some RAM tested).\n  3 = Blend (tests some of everything, lots of RAM tested).\n  11,12,13 = Allows you to fine tune the above three selections.\nBlend is the default.  NOTE: if you fail the blend test, but can pass the small FFT test then your problem is likely bad memory or a bad memory controller.\n");
	m_type = 3;
	askNum ("Type of torture test to run", &m_type, 1, 13);

	if (m_type == 1 || m_type == 11) {
		m_minfft = 8;
		m_maxfft = 64;
		m_memory = 0;
	}
	else if (m_type == 2 || m_type == 12) {
		m_minfft = 128;
		m_maxfft = 1024;
		m_memory = 0;
	} else {
		m_minfft = 8;
		m_maxfft = 4096;
		m_memory = blendmemory;
	}

	if (m_type >= 11) {
		askNum ("Min FFT size (in K)", &m_minfft, (CPU_FLAGS & CPU_AVX) ? 0 : 7,
			(CPU_FLAGS & CPU_SSE2 ? MAX_FFTLEN_SSE2 : MAX_FFTLEN) / 1024);
		askNum ("Max FFT size (in K)", &m_maxfft, (CPU_FLAGS & CPU_AVX) ? 1 : 7,
			(CPU_FLAGS & CPU_SSE2 ? MAX_FFTLEN_SSE2 : MAX_FFTLEN) / 1024);
		if (blendmemory > 8)
			askNum ("Memory to use (in MB, 0 = in-place FFTs)", &m_memory, 0, mem);
		askNum ("Time to run each FFT size (in minutes)", &m_timefft, 1, 60);
	}

	if (askOkCancel ()) {
		IniWriteInt (INI_FILE, "MinTortureFFT", m_minfft);
		IniWriteInt (INI_FILE, "MaxTortureFFT", m_maxfft);
		mem = m_memory / m_thread;
		IniWriteInt (INI_FILE, "TortureMem", mem);
		IniWriteInt (INI_FILE, "TortureTime", m_timefft);
		LaunchTortureTest (m_thread, TRUE);
	}
}
Esempio n. 6
0
void options_preferences (void)
{
	unsigned long m_iter, m_r_iter, m_disk_write_time;
	unsigned long m_modem, m_retry, m_work, m_backup;
	float	m_end_dates;
	int	m_noise, m_battery;

	m_iter = ITER_OUTPUT;
	m_r_iter = ITER_OUTPUT_RES;
	m_disk_write_time = DISK_WRITE_TIME;
	m_modem = MODEM_RETRY_TIME;
	m_retry = NETWORK_RETRY_TIME;
	m_work = DAYS_OF_WORK;
	m_end_dates = DAYS_BETWEEN_CHECKINS;
	m_backup = NUM_BACKUP_FILES;
	m_noise = !SILENT_VICTORY;
	m_battery = RUN_ON_BATTERY;

	askNum ("Iterations between screen outputs", &m_iter, 1, 999999999);
	askNum ("Iterations between results file outputs",
		&m_r_iter, 10000, 999999999);
	askNum ("Minutes between disk writes", &m_disk_write_time, 10, 999999);
	if (USE_PRIMENET && DIAL_UP)
		askNum ("Minutes between modem retries", &m_modem, 1, 300);
	if (USE_PRIMENET)
		askNum ("Minutes between network retries", &m_retry, 1, 300);
	if (USE_PRIMENET)
		askNum ("Days of work to queue up", &m_work, 1, 90);
	if (USE_PRIMENET)
		askFloat ("Days between sending end dates", &m_end_dates, 0.125, 7);
	askNum ("Number of Backup Files", &m_backup, 1, 3);
	askYN ("Make noise if new Mersenne prime is found", &m_noise);
	askYN ("Run program even when using laptop battery power", &m_battery);

	if (askOkCancel ()) {
		ITER_OUTPUT = m_iter;
		ITER_OUTPUT_RES = m_r_iter;
		DISK_WRITE_TIME = m_disk_write_time;
		MODEM_RETRY_TIME = m_modem;
		NETWORK_RETRY_TIME = m_retry;
		DAYS_OF_WORK = m_work;
		DAYS_BETWEEN_CHECKINS = m_end_dates;
		NUM_BACKUP_FILES = m_backup;
		SILENT_VICTORY = !m_noise;
		if (RUN_ON_BATTERY != m_battery) {
			RUN_ON_BATTERY = m_battery;
			IniWriteInt (LOCALINI_FILE, "RunOnBattery", RUN_ON_BATTERY);
			run_on_battery_changed ();
		}
		IniWriteInt (INI_FILE, "OutputIterations", ITER_OUTPUT);
		IniWriteInt (INI_FILE, "ResultsFileIterations", ITER_OUTPUT_RES);
		IniWriteInt (INI_FILE, "DiskWriteTime", DISK_WRITE_TIME);
		IniWriteInt (INI_FILE, "NetworkRetryTime", MODEM_RETRY_TIME);
		IniWriteInt (INI_FILE, "NetworkRetryTime2", NETWORK_RETRY_TIME);
		IniWriteInt (INI_FILE, "DaysOfWork", DAYS_OF_WORK);
		IniWriteFloat (INI_FILE, "DaysBetweenCheckins", DAYS_BETWEEN_CHECKINS);
		IniWriteInt (INI_FILE, "NumBackupFiles", NUM_BACKUP_FILES);
		IniWriteInt (INI_FILE, "SilentVictory", SILENT_VICTORY);
		spoolMessage (PRIMENET_PROGRAM_OPTIONS, NULL);
	}
}
Esempio n. 7
0
void options_cpu (void)
{
	unsigned int day_memory, night_memory, day_start_time, day_end_time;
	unsigned long m_hours, m_day_memory, m_night_memory, max_mem;
	int	m_memory_editable;
	char m_start_time[13];
	char m_end_time[13];
	char buf[512];

	m_memory_editable =
		read_memory_settings (&day_memory, &night_memory,
				      &day_start_time, &day_end_time);
//again:
	m_hours = CPU_HOURS;
	m_day_memory = day_memory;
	m_night_memory = night_memory;
	minutesToStr (day_start_time, m_start_time);
	minutesToStr (day_end_time, m_end_time);

	askNum ("Hours per day this program will run", &m_hours, 1, 24);

	printf ("\nPlease see the readme.txt file for important\n");
	printf ("information on the P-1/ECM stage 2 memory settings.\n\n");

	if (m_memory_editable) {
		max_mem = physical_memory () - 8;
		if (max_mem < 8) max_mem = 8;
		askNum ("Daytime P-1/ECM stage 2 memory in MB", &m_day_memory, 8, max_mem);
		askNum ("Nighttime P-1/ECM stage 2 memory in MB", &m_night_memory, 8, max_mem);
		if (m_day_memory != m_night_memory) {
			askStr ("Daytime begins at", (char *) &m_start_time, 12);
			askStr ("Daytime ends at", (char *) &m_end_time, 12);
		}
	}

	getCpuDescription (buf, 0);
	printf ("\nCPU Information:\n%s\n", buf);

	if (askOkCancel ()) {
		unsigned int new_day_start_time, new_day_end_time;

		if (CPU_HOURS != m_hours) {
			CPU_HOURS = m_hours;
			IniWriteInt (LOCALINI_FILE, "CPUHours", CPU_HOURS);
			ROLLING_AVERAGE = 1000;
			IniWriteInt (LOCALINI_FILE, "RollingAverage", 1000);
			IniWriteInt (LOCALINI_FILE, "RollingStartTime", 0);
			spoolMessage (PRIMENET_UPDATE_COMPUTER_INFO, NULL);
			delete_timed_event (TE_COMM_SERVER);
			UpdateEndDates ();
		}
		new_day_start_time = strToMinutes ((char *) &m_start_time);
		new_day_end_time = strToMinutes ((char *) &m_end_time);
		if (m_memory_editable &&
		    (day_memory != m_day_memory ||
		     night_memory != m_night_memory ||
		     day_start_time != new_day_start_time ||
		     day_end_time != new_day_end_time)) {
			write_memory_settings (m_day_memory, m_night_memory,
					       new_day_start_time, new_day_end_time);
			mem_settings_have_changed ();
		}
		spoolMessage (PRIMENET_PROGRAM_OPTIONS, NULL);

// Now that Primenet almost always hands out LL assignments that are P-1'ed,
// there is little reason to prompt user into allowing us to use more memory.
//		if (!IniGetInt (INI_FILE, "AskedAboutMemory", 0)) {
//			IniWriteInt (INI_FILE, "AskedAboutMemory", 1);
//			if (m_day_memory == 8 && m_night_memory == 8) {
//				outputLongLine (MSG_MEMORY);
//				if (askYesNo ('Y')) goto again;
//			}
//		}
	} else
		STARTUP_IN_PROGRESS = 0;
}
Esempio n. 8
0
void test_worker_threads (void)
{
	unsigned long m_num_thread, m_priority;
	unsigned long m_work_pref[MAX_NUM_WORKER_THREADS];
	unsigned long m_affinity[MAX_NUM_WORKER_THREADS];
	unsigned long m_numcpus[MAX_NUM_WORKER_THREADS];
	int	i;

	m_num_thread = NUM_WORKER_THREADS;
	m_priority = PRIORITY;
	for (i = 0; i < MAX_NUM_WORKER_THREADS; i++) {
		m_work_pref[i] = WORK_PREFERENCE[i];
		m_affinity[i] = CPU_AFFINITY[i];
		m_numcpus[i] = THREADS_PER_TEST[i];
	}

again:	if (max_num_workers () > 1)
		askNum ("Number of workers to run", &m_num_thread, 1, max_num_workers ());

	outputLongLine ("\nPick a priority between 1 and 10 where 1 is the lowest priority and 10 is the highest.  It is strongly recommended that you use the default priority of 1.  Your throughput will probably not improve by using a higher priority.  The only time you should raise the priority is when another process, such as a screen saver, is stealing CPU cycles from this program.\n");
	askNum ("Priority", &m_priority, 1, 10);

	if (USE_PRIMENET) {
		outputLongLine ("\nUse the following values to select a work type:\n  0 - Whatever makes the most sense\n  2 - Trial factoring\n 100 - First time primality tests\n  101 - Double-checking\n  102 - World record primality tests\n  4 - P-1 factoring\n  104 - 100 million digit primality tests\n  1 - Trial factoring to low limits\n  5 - ECM on small Mersenne numbers\n  6 - ECM on Fermat numbers\n");
	}

	if (USE_PRIMENET || NUM_CPUS * user_configurable_hyperthreads () > 1) {
	    for (i = 0; i < m_num_thread; i++) {
		if (m_num_thread > 1)
			printf ("\nOptions for worker #%d\n\n", i+1);
		else
			printf ("\n");

		if (USE_PRIMENET) {
			askNum ("Type of work to get", &m_work_pref[i], 0, 150);
			if (m_numcpus[i] < min_cores_for_work_type (m_work_pref[i]))
				m_numcpus[i] = min_cores_for_work_type (m_work_pref[i]);
		}

		if (NUM_CPUS * user_configurable_hyperthreads () > 1) {
			char question[200];
			unsigned long affinity;
			sprintf (question,
				 "CPU affinity (1-%d=specific CPU, 99=any CPU, 100=smart assignment)",
				 (int) (NUM_CPUS * CPU_HYPERTHREADS));
			affinity = m_affinity[i];
			if (affinity < 99) affinity++;
			askNum (question, &affinity, 1, 100);
			if (affinity < 99) affinity--;
			m_affinity[i] = affinity;
		}

		if (NUM_CPUS * user_configurable_hyperthreads () > 1) {
			int min_cores, max_cores;
			min_cores = min_cores_for_work_type (m_work_pref[i]);
			max_cores = NUM_CPUS * user_configurable_hyperthreads () - m_num_thread + 1;
			if (max_cores < min_cores) max_cores = min_cores;
			askNum ("CPUs to use (multithreading)", &m_numcpus[i], min_cores, max_cores);
		} else
			m_numcpus[i] = 1;
	    }
	}

/* Ask user if they are happy with their answers */

	if (askOkCancel ()) {
		int	restart = FALSE;
		int	new_options = FALSE;
		unsigned long i, total_num_threads;

/* If the user has allocated more threads than there are CPUs, raise a */
/* severe warning. */

		total_num_threads = 0;
		for (i = 0; i < m_num_thread; i++)
			total_num_threads += m_numcpus[i];
		if (total_num_threads > NUM_CPUS * user_configurable_hyperthreads ()) {
			outputLongLine (MSG_THREADS);
			if (askYesNo ('Y')) goto again;
		}

/* If user is changing the number of worker threads, then make the */
/* necessary changes.  Restart worker threads so that we are running */
/* the correct number of worker threads. */

		if (m_num_thread != NUM_WORKER_THREADS) {
//bug= do something with orphaned work units?
//bug- tell server of the change?
			NUM_WORKER_THREADS = m_num_thread;
			IniWriteInt (LOCALINI_FILE, "WorkerThreads", NUM_WORKER_THREADS);
			restart = TRUE;
		}

/* If user is changing the priority of worker threads, then change */
/* the INI file.  Restart worker threads so that they are running at */
/* the new priority. */

		if (PRIORITY != m_priority) {
			PRIORITY = m_priority;
			IniWriteInt (INI_FILE, "Priority", PRIORITY);
			new_options = TRUE;
			restart = TRUE;
		}

/* If the user changes any of the work preferences record it in the INI file */
/* and tell the server */

		if (AreAllTheSame (m_work_pref, m_num_thread)) {
			if (! PTOIsGlobalOption (WORK_PREFERENCE) ||
			    WORK_PREFERENCE[0] != m_work_pref[0]) {
				PTOSetAll (INI_FILE, "WorkPreference", NULL,
					   WORK_PREFERENCE, m_work_pref[0]);
				new_options = TRUE;
			}
		} else {
			for (i = 0; i < (int) NUM_WORKER_THREADS; i++) {
				if (WORK_PREFERENCE[i] == m_work_pref[i])
					continue;
				PTOSetOne (INI_FILE, "WorkPreference", NULL,
					   WORK_PREFERENCE, i,
					   m_work_pref[i]);
				new_options = TRUE;
			}
		}

/* If the user changes any of the affinities record it in the INI file. */

		if (AreAllTheSame (m_affinity, m_num_thread)) {
			PTOSetAll (LOCALINI_FILE, "Affinity", NULL,
				   CPU_AFFINITY, m_affinity[0]);
		} else {
			for (i = 0; i < (int) NUM_WORKER_THREADS; i++) {
				PTOSetOne (LOCALINI_FILE, "Affinity", NULL,
					   CPU_AFFINITY, i, m_affinity[i]);
			}
		}

/* If the user changes any of the threads_per_test record it in the INI file */

		if (AreAllTheSame (m_numcpus, m_num_thread)) {
			PTOSetAll (LOCALINI_FILE, "ThreadsPerTest", NULL,
				   THREADS_PER_TEST, m_numcpus[0]);
		} else {
			for (i = 0; i < (int) NUM_WORKER_THREADS; i++) {
				PTOSetOne (LOCALINI_FILE, "ThreadsPerTest", NULL,
					   THREADS_PER_TEST, i, m_numcpus[i]);
			}
		}

/* Send new settings to the server */

		if (new_options) spoolMessage (PRIMENET_PROGRAM_OPTIONS, NULL);

/* Restart worker threads with new options */

		if (restart) stop_workers_for_restart ();
	} else
		STARTUP_IN_PROGRESS = 0;
}
Esempio n. 9
0
void test_primenet (void)
{
	int	m_primenet, m_dialup;
	unsigned long m_proxy_port, m_debug;
	char	m_userid[21], m_compid[21], m_proxy_host[121];
	char	m_proxy_user[51], m_proxy_pwd[51], orig_proxy_pwd[51];
	unsigned short proxy_port;
	int	update_computer_info, primenet_debug;
	char	m_username[81], m_userpwd[14];

	update_computer_info = FALSE;
	primenet_debug = IniSectionGetInt (INI_FILE, "PrimeNet", "Debug", 0);

	m_primenet = USE_PRIMENET;
	if (strcmp (USERID, "ANONYMOUS") == 0)
		m_userid[0] = 0;
	else
		strcpy (m_userid, USERID);
	strcpy (m_compid, COMPID);
	m_dialup = DIAL_UP;
	getProxyInfo (m_proxy_host, &proxy_port, m_proxy_user, m_proxy_pwd);
	m_proxy_port = proxy_port;
	strcpy (orig_proxy_pwd, m_proxy_pwd);
	m_debug = primenet_debug;

	askYN ("Use PrimeNet to get work and report results", &m_primenet);
	if (!m_primenet) goto done;

	outputLongLine ("\nYou must first create your user ID at mersenne.org or leave user ID blank to run anonymously.  See the readme.txt file for details.\n");
	askStr ("Optional user ID", m_userid, 20);
	askStr ("Optional computer name", m_compid, 20);

	askYN ("Computer uses a dial-up connection to the Internet", &m_dialup);

	askStr ("Optional proxy host name", m_proxy_host, 120);
	if (!m_proxy_host[0]) goto done;

	askNum ("Proxy port number", &m_proxy_port, 1, 65535);
	askStr ("Optional proxy user name", m_proxy_user, 50);
	askStr ("Optional proxy password", m_proxy_pwd, 50);
	askNum ("Output debug info to prime.log (0=none, 1=some, 2=lots)", &m_debug, 0, 2);

done:	if (askOkCancel ()) {
		DIAL_UP = m_dialup;
		IniWriteInt (INI_FILE, "DialUp", DIAL_UP);

		if (m_proxy_host[0] && m_proxy_port != 8080)
			sprintf (m_proxy_host + strlen (m_proxy_host), ":%lu", m_proxy_port);
		IniSectionWriteString (INI_FILE, "PrimeNet", "ProxyHost", m_proxy_host);
		if (m_proxy_host[0]) {
			IniSectionWriteString (INI_FILE, "PrimeNet", "ProxyUser", m_proxy_user);
			if (strcmp (m_proxy_pwd, orig_proxy_pwd)) {
				IniSectionWriteString (INI_FILE, "PrimeNet",
					"ProxyPass", m_proxy_pwd);
				IniSectionWriteInt (INI_FILE, "PrimeNet",
					"ProxyMask", 0);
			}
		}
		if (m_debug != primenet_debug) {
			IniSectionWriteInt (INI_FILE, "PrimeNet", "Debug",
					    m_debug);
		}

		if (m_userid[0] == 0)
			strcpy (m_userid, "ANONYMOUS");

		if (strcmp (USERID, m_userid) != 0) {
			strcpy (USERID, m_userid);
			sanitizeString (USERID);
			IniWriteString (INI_FILE, "V5UserID", USERID);
			update_computer_info = TRUE;
		}
		if (strcmp (COMPID, m_compid) != 0) {
			strcpy (COMPID, m_compid);
			sanitizeString (COMPID);
			IniWriteString (LOCALINI_FILE, "ComputerID", COMPID);
			update_computer_info = TRUE;
		}

		if (!USE_PRIMENET && m_primenet) {
			USE_PRIMENET = 1;
			create_window (COMM_THREAD_NUM);
			base_title (COMM_THREAD_NUM, "Communication thread");
			if (!STARTUP_IN_PROGRESS) set_comm_timers ();
			spoolMessage (PRIMENET_UPDATE_COMPUTER_INFO, NULL);
			spoolExistingResultsFile ();
		} else if (USE_PRIMENET && !m_primenet) {
			USE_PRIMENET = 0;
			if (!STARTUP_IN_PROGRESS) set_comm_timers ();
		} else if (update_computer_info)
			spoolMessage (PRIMENET_UPDATE_COMPUTER_INFO, NULL);

		IniWriteInt (INI_FILE, "UsePrimenet", USE_PRIMENET);
		spoolMessage (PRIMENET_PROGRAM_OPTIONS, NULL);
	} else
		STARTUP_IN_PROGRESS = 0;
}