1217309Snwhitehorn/* Copyright (C) 1995 Florian La Roche */
2217309Snwhitehorn/* Who wants to help coding? I don't like doing this... */
3217309Snwhitehorn
4217309Snwhitehorn/* You can just start setup as normal user and see how far it is coded
5217309Snwhitehorn   right now. This will do a fake installation and won't actually chnage
6217309Snwhitehorn   any data on your computer. */
7217309Snwhitehorn
8217309Snwhitehorn/* TODO: write a good package selection code
9217309Snwhitehorn         change functions to return better error code
10217309Snwhitehorn */
11217309Snwhitehorn
12217309Snwhitehorn/* Show an extra text-box with the contents of all external commands,
13217309Snwhitehorn   before they are executed. So you can abort the installation, if any
14217309Snwhitehorn   wrong commands are to be executed. (So don't format wrong partition.) */
15217309Snwhitehorn#define VERBOSE 1
16217309Snwhitehorn
17217309Snwhitehorn/* If defined, don't actually execute any comands and don't actually modify
18217309Snwhitehorn   any files. So you can test any possible installation without doing any
19217309Snwhitehorn   damage to your computer.
20217309Snwhitehorn   The file FDISK.TEST is used instead of real "fdisk -l" output, so that
21217309Snwhitehorn   it can be started as normal user. */
22217309Snwhitehorn#define DEBUG_THIS 1
23217309Snwhitehorn
24217309Snwhitehorn#include <dialog.h>
25217309Snwhitehorn
26217309Snwhitehorn/* max length of a partition name like e.g. '/dev/hda1' */
27217309Snwhitehorn#define MAX_DEV_NAME 25
28217309Snwhitehorn
29217309Snwhitehorn/* max number of possible Linux/Swap/MsDos partitions */
30217309Snwhitehorn#define MAX_PARTS 20
31217309Snwhitehorn
32217309Snwhitehornchar *progname = NULL;
33217309Snwhitehorn
34217309Snwhitehornstatic void
35217309Snwhitehornerror(const char *s)
36217309Snwhitehorn{
37217309Snwhitehorn    fprintf(stderr, "%s: %s\n", progname, s);
38217309Snwhitehorn    exit(1);
39217309Snwhitehorn}
40217309Snwhitehorn
41217309Snwhitehornstatic int
42217309Snwhitehornmy_system(const char *s,...)
43217309Snwhitehorn{
44217309Snwhitehorn    int ret, i;
45217309Snwhitehorn    va_list ap;
46217309Snwhitehorn    char sh[200];
47217309Snwhitehorn
48217309Snwhitehorn    va_start(ap, s);
49217309Snwhitehorn    vsprintf(sh, s, ap);
50217309Snwhitehorn    va_end(ap);
51217309Snwhitehorn
52217309Snwhitehorn#ifdef	VERBOSE
53217309Snwhitehorn    i = dialog_msgbox("I will run the following command:", sh, 10, 65, 1);
54217309Snwhitehorn    dialog_clear();
55217309Snwhitehorn#ifdef DEBUG_THIS
56217309Snwhitehorn    return 0;
57217309Snwhitehorn#endif
58217309Snwhitehorn#endif
59217309Snwhitehorn    ret = system(sh);
60217309Snwhitehorn    if (!(ret >> 8))
61217309Snwhitehorn	return 0;
62217309Snwhitehorn    i = dialog_msgbox("Error-Exit on the following command:",
63217309Snwhitehorn		      sh, 12, 73, 1);
64217309Snwhitehorn    dialog_clear();
65217309Snwhitehorn    return 1;
66217309Snwhitehorn}
67217309Snwhitehorn
68217309Snwhitehorn/* We support to install from DOS/Linux-partitions. */
69217309Snwhitehornenum partition_type {
70217309Snwhitehorn    MsDos,
71217309Snwhitehorn    Linux,
72217309Snwhitehorn    Swap
73217309Snwhitehorn};
74217309Snwhitehorn
75217309Snwhitehornstruct partition {
76217309Snwhitehorn    enum partition_type type;
77217309Snwhitehorn    char name[MAX_DEV_NAME];
78217309Snwhitehorn    int blocks;
79217309Snwhitehorn    int flag;
80217309Snwhitehorn} partitions[MAX_PARTS];
81217309Snwhitehornint num_partition = 0;
82217309Snwhitehornint num_linux = 0;
83217309Snwhitehornint num_swap = 0;
84217309Snwhitehornint num_msdos = 0;
85217309Snwhitehorn
86217309Snwhitehornstatic int
87217309Snwhitehornget_line(char *line, int size, FILE * f)
88217309Snwhitehorn{
89217309Snwhitehorn    char *ptr = line;
90217309Snwhitehorn    int c;
91217309Snwhitehorn
92217309Snwhitehorn    if (feof(f))
93217309Snwhitehorn	return -1;
94217309Snwhitehorn    while (size-- && ((c = getc(f)) != EOF) && (c != '\n'))
95217309Snwhitehorn	*ptr++ = c;
96217309Snwhitehorn    *ptr++ = '\0';
97217309Snwhitehorn    return (int) (ptr - line);
98217309Snwhitehorn}
99217309Snwhitehorn
100217309Snwhitehornstatic void
101217309Snwhitehornread_partitions(void)
102217309Snwhitehorn{
103217309Snwhitehorn    FILE *f;
104217309Snwhitehorn    char line[200];
105217309Snwhitehorn    int length;
106217309Snwhitehorn#ifndef DEBUG_THIS
107217309Snwhitehorn    int ret = system("fdisk -l 2>/dev/null 1>/tmp/fdisk.output");
108217309Snwhitehorn    if ((ret >> 8) != 0) {
109217309Snwhitehorn	error("fdisk didn't run");
110217309Snwhitehorn    }
111217309Snwhitehorn    if ((f = fopen("/tmp/fdisk.output", "r")) == NULL)
112217309Snwhitehorn#else
113217309Snwhitehorn    if ((f = fopen("FDISK.TEST", "r")) == NULL)
114217309Snwhitehorn#endif
115217309Snwhitehorn	error("cannot read fdisk output");
116217309Snwhitehorn
117217309Snwhitehorn    while (num_partition <= MAX_PARTS
118217309Snwhitehorn	   && (length = get_line(line, 200, f)) >= 0) {
119217309Snwhitehorn	if (strncmp(line, "/dev/", 5) == 0) {
120217309Snwhitehorn	    int n = 0;
121217309Snwhitehorn	    char *s = line + 5;
122217309Snwhitehorn	    char *t = partitions[num_partition].name;
123217309Snwhitehorn	    strcpy(t, "/dev/");
124217309Snwhitehorn	    t += 5;
125217309Snwhitehorn	    while (n < MAX_DEV_NAME && *s != '\0'
126217309Snwhitehorn		   && !isspace((unsigned char) *s)) {
127217309Snwhitehorn		*t++ = *s++;
128217309Snwhitehorn		n++;
129217309Snwhitehorn	    }
130217309Snwhitehorn	    *t = '\0';
131217309Snwhitehorn	    /* Read the size of the partition. */
132217309Snwhitehorn	    t = line + 37;
133217309Snwhitehorn	    while (isspace((unsigned char) *t))
134217309Snwhitehorn		t++;
135217309Snwhitehorn	    partitions[num_partition].blocks = atoi(t);
136217309Snwhitehorn	    if (strstr(line, "Linux native")) {
137217309Snwhitehorn		partitions[num_partition].type = Linux;
138217309Snwhitehorn		num_partition++;
139217309Snwhitehorn		num_linux++;
140217309Snwhitehorn	    } else if (strstr(line, "Linux swap")) {
141217309Snwhitehorn		partitions[num_partition].type = Swap;
142217309Snwhitehorn		num_partition++;
143217309Snwhitehorn		num_swap++;
144217309Snwhitehorn	    } else if (strstr(line, "DOS")) {
145217309Snwhitehorn		partitions[num_partition].type = MsDos;
146217309Snwhitehorn		num_partition++;
147217309Snwhitehorn		num_msdos++;
148217309Snwhitehorn	    }
149217309Snwhitehorn	}
150217309Snwhitehorn    }
151217309Snwhitehorn    fclose(f);
152217309Snwhitehorn#ifndef DEBUG_THIS
153217309Snwhitehorn    unlink("/tmp/fdisk.output");
154217309Snwhitehorn#endif
155217309Snwhitehorn}
156217309Snwhitehorn
157217309Snwhitehornstatic int
158217309Snwhitehornselect_partition(const char *title, const char *prompt, int y, int x)
159217309Snwhitehorn{
160217309Snwhitehorn    int i, num, ret;
161217309Snwhitehorn    char info[MAX_PARTS][40];
162217309Snwhitehorn    char *items[MAX_PARTS * 2];
163217309Snwhitehorn    int num_pa[MAX_PARTS];
164217309Snwhitehorn
165217309Snwhitehorn    num = 0;
166217309Snwhitehorn    for (i = 0; i < num_partition; i++) {
167217309Snwhitehorn	if (partitions[i].type == Linux) {
168217309Snwhitehorn	    items[num * 2] = partitions[i].name;
169217309Snwhitehorn	    sprintf(info[num], "Linux partition with %d blocks",
170217309Snwhitehorn		    partitions[i].blocks);
171217309Snwhitehorn	    items[num * 2 + 1] = info[num];
172217309Snwhitehorn	    num_pa[num] = i;
173217309Snwhitehorn	    num++;
174217309Snwhitehorn	}
175217309Snwhitehorn    }
176217309Snwhitehorn    ret = dialog_menu(title, prompt, y + num, x, num, num, items);
177217309Snwhitehorn    dialog_clear();
178217309Snwhitehorn    if (ret >= 0)		/* item selected */
179217309Snwhitehorn	ret = num_pa[ret];
180217309Snwhitehorn    return ret;
181217309Snwhitehorn}
182217309Snwhitehorn
183217309Snwhitehornstatic int
184217309Snwhitehornselect_install_partition(void)
185217309Snwhitehorn{
186217309Snwhitehorn    return select_partition("Select Install Partition",
187217309Snwhitehorn			    "\\nWhere do you want to install Linux?\\n", 9, 60);
188217309Snwhitehorn}
189217309Snwhitehorn
190217309Snwhitehornstatic int
191217309Snwhitehornselect_source_partition(void)
192217309Snwhitehorn{
193217309Snwhitehorn    return select_partition("Select Source Partition",
194217309Snwhitehorn			    "\\nOn which partition is the source?\\n", 9, 60);
195217309Snwhitehorn}
196217309Snwhitehorn
197217309Snwhitehornconst char *null = ">/dev/null 2>/dev/null";
198217309Snwhitehornconst char *install_partition = NULL;
199217309Snwhitehorn
200217309Snwhitehornstatic void
201217309Snwhitehornextract_packages(const char *source_path)
202217309Snwhitehorn{
203217309Snwhitehorn#ifndef	DEBUG_THIS
204217309Snwhitehorn    FILE *f;
205217309Snwhitehorn#endif
206217309Snwhitehorn
207217309Snwhitehorn    if (my_system("mkdir -p /install/var/installed/packages %s", null))
208217309Snwhitehorn	return;
209217309Snwhitehorn    if (my_system("cd /install; for i in /source%s/*.tgz; do "
210217309Snwhitehorn		  "tar xzplvvkf $i >> var/installed/packages/base "
211217309Snwhitehorn		  "2>>var/installed/packages/ERROR; done", source_path))
212217309Snwhitehorn	return;
213217309Snwhitehorn#ifndef	DEBUG_THIS
214217309Snwhitehorn    if ((f = fopen("/install/etc/fstab", "w")) == NULL) {
215217309Snwhitehorn	/* i = */ dialog_msgbox("Error", "Cannot write /etc/fstab",
216217309Snwhitehorn				12, 40, 1);
217217309Snwhitehorn	return;
218217309Snwhitehorn    }
219217309Snwhitehorn    fprintf(f, "%s / ext2 defaults 1 1\n", install_partition);
220217309Snwhitehorn    fprintf(f, "none /proc proc defaults 0 2\n");
221217309Snwhitehorn    /* XXX write swap-partitions */
222217309Snwhitehorn    fclose(f);
223217309Snwhitehorn#endif
224217309Snwhitehorn}
225217309Snwhitehorn
226217309Snwhitehornstatic void
227217309Snwhitehorninstall_premounted(void)
228217309Snwhitehorn{
229217309Snwhitehorn    extract_packages("");
230217309Snwhitehorn}
231217309Snwhitehorn
232217309Snwhitehornstatic void
233217309Snwhitehorninstall_harddisk(void)
234217309Snwhitehorn{
235217309Snwhitehorn    const char *name;
236217309Snwhitehorn    int part, ret;
237217309Snwhitehorn
238217309Snwhitehorn    if ((part = select_source_partition()) <= -1)
239217309Snwhitehorn	return;
240217309Snwhitehorn    name = partitions[part].name;
241217309Snwhitehorn
242217309Snwhitehorn    if (my_system("mount -t ext2 %s /source %s", name, null))
243217309Snwhitehorn	return;
244217309Snwhitehorn    ret = dialog_inputbox("Path in partition",
245217309Snwhitehorn			  "Please enter the directory in which the "
246217309Snwhitehorn			  "source files are.", 13, 50, "", FALSE);
247217309Snwhitehorn    dialog_clear();
248217309Snwhitehorn    if (ret != 0)
249217309Snwhitehorn	return;
250217309Snwhitehorn    /* XXX strdup */
251217309Snwhitehorn    extract_packages(strdup(dialog_input_result));
252217309Snwhitehorn    if (my_system("umount /source %s", null))
253217309Snwhitehorn	return;
254217309Snwhitehorn}
255217309Snwhitehorn
256217309Snwhitehornstatic void
257217309Snwhitehorninstall_nfs(void)
258217309Snwhitehorn{
259217309Snwhitehorn    if (my_system("ifconfig eth0 134.96.81.36 netmask 255.255.255.224 "
260217309Snwhitehorn		  "broadcast 134.96.81.63 %s", null))
261217309Snwhitehorn	return;
262217309Snwhitehorn    if (my_system("route add -net 134.96.81.32 %s", null))
263217309Snwhitehorn	return;
264217309Snwhitehorn    if (my_system("mount -t nfs 134.96.81.38:"
265217309Snwhitehorn		  "/local/ftp/pub/linux/ELF.binary/tar /source %s", null))
266217309Snwhitehorn	return;
267217309Snwhitehorn    extract_packages("/base");
268217309Snwhitehorn    if (my_system("umount /source %s", null))
269217309Snwhitehorn	return;
270217309Snwhitehorn    if (my_system("ifconfig eth0 down %s", null))
271217309Snwhitehorn	return;
272217309Snwhitehorn}
273217309Snwhitehorn
274217309Snwhitehornstatic void
275217309Snwhitehornmain_install(void)
276217309Snwhitehorn{
277217309Snwhitehorn    int part, ret;
278217309Snwhitehorn    const char *name;
279217309Snwhitehorn    char *items1[] =
280217309Snwhitehorn    {
281217309Snwhitehorn	"1", "Harddisk Install",
282217309Snwhitehorn	"2", "Network Install(NFS)",
283217309Snwhitehorn	"3", "Premounted on /source"
284217309Snwhitehorn    };
285217309Snwhitehorn
286217309Snwhitehorn    if (num_linux == 0) {
287217309Snwhitehorn	/* XXX */
288217309Snwhitehorn	return;
289217309Snwhitehorn    }
290217309Snwhitehorn    if ((part = select_install_partition()) <= -1)
291217309Snwhitehorn	return;
292217309Snwhitehorn    install_partition = name = partitions[part].name;
293217309Snwhitehorn    if (my_system("mke2fs %s %s", name, null))
294217309Snwhitehorn	return;
295217309Snwhitehorn    if (my_system("mount -t ext2 %s /install %s", name, null))
296217309Snwhitehorn	return;
297217309Snwhitehorn    ret = dialog_menu("Choose install medium",
298217309Snwhitehorn		      "\\nPlease say from where you want to install.\\n",
299217309Snwhitehorn		      12, 62, 3, 3, items1);
300217309Snwhitehorn    dialog_clear();
301217309Snwhitehorn    switch (ret) {
302217309Snwhitehorn    case 0:
303217309Snwhitehorn	install_harddisk();
304217309Snwhitehorn	break;
305217309Snwhitehorn    case 1:
306217309Snwhitehorn	install_nfs();
307217309Snwhitehorn	break;
308217309Snwhitehorn    case 2:
309217309Snwhitehorn	install_premounted();
310217309Snwhitehorn	break;
311217309Snwhitehorn    case -2:			/* cancel */
312217309Snwhitehorn    case -1:
313217309Snwhitehorn	break;			/* esc */
314217309Snwhitehorn    }
315217309Snwhitehorn    if (my_system("umount /install %s", null))
316217309Snwhitehorn	return;
317217309Snwhitehorn}
318217309Snwhitehorn
319217309Snwhitehornint
320217309Snwhitehornmain(int argc, char **argv)
321217309Snwhitehorn{
322217309Snwhitehorn    int stop = 0;
323217309Snwhitehorn    int ret;
324217309Snwhitehorn    char *items1[] =
325217309Snwhitehorn    {
326217309Snwhitehorn	"1", "Display a help text",
327217309Snwhitehorn	"2", "Start an installation",
328217309Snwhitehorn	"3", "Exit to the shell"
329217309Snwhitehorn    };
330217309Snwhitehorn
331217309Snwhitehorn    progname = argv[0];
332217309Snwhitehorn
333217309Snwhitehorn    read_partitions();
334217309Snwhitehorn    if (num_linux == 0) {
335217309Snwhitehorn	printf("\n\nPlease start \"fdisk\" or \"cfdisk\" and create a"
336217309Snwhitehorn	       "\nnative Linux-partition to install Linux on.\n\n");
337217309Snwhitehorn	exit(1);
338217309Snwhitehorn    }
339217309Snwhitehorn
340217309Snwhitehorn    init_dialog();
341217309Snwhitehorn
342217309Snwhitehorn    while (!stop) {
343217309Snwhitehorn	ret = dialog_menu("Linux Install Utility",
344217309Snwhitehorn			  "\\nCopyright (C) 1995 Florian La Roche\\n"
345217309Snwhitehorn			  "\\nPre-Alpha version, be careful, read the doc!!!"
346217309Snwhitehorn			  "\\nemail: florian@jurix.jura.uni-sb.de, "
347217309Snwhitehorn			  "flla@stud.uni-sb.de\\n",
348217309Snwhitehorn			  15, 64, 3, 3, items1);
349217309Snwhitehorn	dialog_clear();
350217309Snwhitehorn	switch (ret) {
351217309Snwhitehorn	case 0:
352217309Snwhitehorn	    ret = dialog_textbox("Help Text",
353217309Snwhitehorn				 "setup.help", 20, 70);
354217309Snwhitehorn	    dialog_clear();
355217309Snwhitehorn	    break;
356217309Snwhitehorn	case 1:
357217309Snwhitehorn	    main_install();
358217309Snwhitehorn	    break;
359217309Snwhitehorn	case 2:
360217309Snwhitehorn	    stop = 1;
361217309Snwhitehorn	    break;
362217309Snwhitehorn	case -2:		/* cancel */
363217309Snwhitehorn	case -1:
364217309Snwhitehorn	    stop = 1;		/* esc */
365217309Snwhitehorn	}
366217309Snwhitehorn    }
367217309Snwhitehorn    end_dialog();
368217309Snwhitehorn    printf("\nExecute \"reboot\" to restart your computer...\n");
369217309Snwhitehorn
370217309Snwhitehorn    exit(0);
371217309Snwhitehorn}
372