]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/dialog/samples/install/setup.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / dialog / samples / install / setup.c
1 /* Copyright (C) 1995 Florian La Roche */
2 /* Who wants to help coding? I don't like doing this... */
3
4 /* You can just start setup as normal user and see how far it is coded
5    right now. This will do a fake installation and won't actually chnage
6    any data on your computer. */
7
8 /* TODO: write a good package selection code
9          change functions to return better error code
10  */
11
12 /* Show an extra text-box with the contents of all external commands,
13    before they are executed. So you can abort the installation, if any
14    wrong commands are to be executed. (So don't format wrong partition.) */
15 #define VERBOSE 1
16
17 /* If defined, don't actually execute any comands and don't actually modify
18    any files. So you can test any possible installation without doing any
19    damage to your computer.
20    The file FDISK.TEST is used instead of real "fdisk -l" output, so that
21    it can be started as normal user. */
22 #define DEBUG_THIS 1
23
24 #include <dialog.h>
25
26 /* max length of a partition name like e.g. '/dev/hda1' */
27 #define MAX_DEV_NAME 25
28
29 /* max number of possible Linux/Swap/MsDos partitions */
30 #define MAX_PARTS 20
31
32 char *progname = NULL;
33
34 static void
35 error(const char *s)
36 {
37     fprintf(stderr, "%s: %s\n", progname, s);
38     exit(1);
39 }
40
41 static int
42 my_system(const char *s,...)
43 {
44     int ret, i;
45     va_list ap;
46     char sh[200];
47
48     va_start(ap, s);
49     vsprintf(sh, s, ap);
50     va_end(ap);
51
52 #ifdef  VERBOSE
53     i = dialog_msgbox("I will run the following command:", sh, 10, 65, 1);
54     dialog_clear();
55 #ifdef DEBUG_THIS
56     return 0;
57 #endif
58 #endif
59     ret = system(sh);
60     if (!(ret >> 8))
61         return 0;
62     i = dialog_msgbox("Error-Exit on the following command:",
63                       sh, 12, 73, 1);
64     dialog_clear();
65     return 1;
66 }
67
68 /* We support to install from DOS/Linux-partitions. */
69 enum partition_type {
70     MsDos,
71     Linux,
72     Swap
73 };
74
75 struct partition {
76     enum partition_type type;
77     char name[MAX_DEV_NAME];
78     int blocks;
79     int flag;
80 } partitions[MAX_PARTS];
81 int num_partition = 0;
82 int num_linux = 0;
83 int num_swap = 0;
84 int num_msdos = 0;
85
86 static int
87 get_line(char *line, int size, FILE * f)
88 {
89     char *ptr = line;
90     int c;
91
92     if (feof(f))
93         return -1;
94     while (size-- && ((c = getc(f)) != EOF) && (c != '\n'))
95         *ptr++ = c;
96     *ptr++ = '\0';
97     return (int) (ptr - line);
98 }
99
100 static void
101 read_partitions(void)
102 {
103     FILE *f;
104     char line[200];
105     int length;
106 #ifndef DEBUG_THIS
107     int ret = system("fdisk -l 2>/dev/null 1>/tmp/fdisk.output");
108     if ((ret >> 8) != 0) {
109         error("fdisk didn't run");
110     }
111     if ((f = fopen("/tmp/fdisk.output", "r")) == NULL)
112 #else
113     if ((f = fopen("FDISK.TEST", "r")) == NULL)
114 #endif
115         error("cannot read fdisk output");
116
117     while (num_partition <= MAX_PARTS
118            && (length = get_line(line, 200, f)) >= 0) {
119         if (strncmp(line, "/dev/", 5) == 0) {
120             int n = 0;
121             char *s = line + 5;
122             char *t = partitions[num_partition].name;
123             strcpy(t, "/dev/");
124             t += 5;
125             while (n < MAX_DEV_NAME && *s != '\0'
126                    && !isspace((unsigned char) *s)) {
127                 *t++ = *s++;
128                 n++;
129             }
130             *t = '\0';
131             /* Read the size of the partition. */
132             t = line + 37;
133             while (isspace((unsigned char) *t))
134                 t++;
135             partitions[num_partition].blocks = atoi(t);
136             if (strstr(line, "Linux native")) {
137                 partitions[num_partition].type = Linux;
138                 num_partition++;
139                 num_linux++;
140             } else if (strstr(line, "Linux swap")) {
141                 partitions[num_partition].type = Swap;
142                 num_partition++;
143                 num_swap++;
144             } else if (strstr(line, "DOS")) {
145                 partitions[num_partition].type = MsDos;
146                 num_partition++;
147                 num_msdos++;
148             }
149         }
150     }
151     fclose(f);
152 #ifndef DEBUG_THIS
153     unlink("/tmp/fdisk.output");
154 #endif
155 }
156
157 static int
158 select_partition(const char *title, const char *prompt, int y, int x)
159 {
160     int i, num, ret;
161     char info[MAX_PARTS][40];
162     char *items[MAX_PARTS * 2];
163     int num_pa[MAX_PARTS];
164
165     num = 0;
166     for (i = 0; i < num_partition; i++) {
167         if (partitions[i].type == Linux) {
168             items[num * 2] = partitions[i].name;
169             sprintf(info[num], "Linux partition with %d blocks",
170                     partitions[i].blocks);
171             items[num * 2 + 1] = info[num];
172             num_pa[num] = i;
173             num++;
174         }
175     }
176     ret = dialog_menu(title, prompt, y + num, x, num, num, items);
177     dialog_clear();
178     if (ret >= 0)               /* item selected */
179         ret = num_pa[ret];
180     return ret;
181 }
182
183 static int
184 select_install_partition(void)
185 {
186     return select_partition("Select Install Partition",
187                             "\\nWhere do you want to install Linux?\\n", 9, 60);
188 }
189
190 static int
191 select_source_partition(void)
192 {
193     return select_partition("Select Source Partition",
194                             "\\nOn which partition is the source?\\n", 9, 60);
195 }
196
197 const char *null = ">/dev/null 2>/dev/null";
198 const char *install_partition = NULL;
199
200 static void
201 extract_packages(const char *source_path)
202 {
203 #ifndef DEBUG_THIS
204     FILE *f;
205 #endif
206
207     if (my_system("mkdir -p /install/var/installed/packages %s", null))
208         return;
209     if (my_system("cd /install; for i in /source%s/*.tgz; do "
210                   "tar xzplvvkf $i >> var/installed/packages/base "
211                   "2>>var/installed/packages/ERROR; done", source_path))
212         return;
213 #ifndef DEBUG_THIS
214     if ((f = fopen("/install/etc/fstab", "w")) == NULL) {
215         /* i = */ dialog_msgbox("Error", "Cannot write /etc/fstab",
216                                 12, 40, 1);
217         return;
218     }
219     fprintf(f, "%s / ext2 defaults 1 1\n", install_partition);
220     fprintf(f, "none /proc proc defaults 0 2\n");
221     /* XXX write swap-partitions */
222     fclose(f);
223 #endif
224 }
225
226 static void
227 install_premounted(void)
228 {
229     extract_packages("");
230 }
231
232 static void
233 install_harddisk(void)
234 {
235     const char *name;
236     int part, ret;
237
238     if ((part = select_source_partition()) <= -1)
239         return;
240     name = partitions[part].name;
241
242     if (my_system("mount -t ext2 %s /source %s", name, null))
243         return;
244     ret = dialog_inputbox("Path in partition",
245                           "Please enter the directory in which the "
246                           "source files are.", 13, 50, "", FALSE);
247     dialog_clear();
248     if (ret != 0)
249         return;
250     /* XXX strdup */
251     extract_packages(strdup(dialog_input_result));
252     if (my_system("umount /source %s", null))
253         return;
254 }
255
256 static void
257 install_nfs(void)
258 {
259     if (my_system("ifconfig eth0 134.96.81.36 netmask 255.255.255.224 "
260                   "broadcast 134.96.81.63 %s", null))
261         return;
262     if (my_system("route add -net 134.96.81.32 %s", null))
263         return;
264     if (my_system("mount -t nfs 134.96.81.38:"
265                   "/local/ftp/pub/linux/ELF.binary/tar /source %s", null))
266         return;
267     extract_packages("/base");
268     if (my_system("umount /source %s", null))
269         return;
270     if (my_system("ifconfig eth0 down %s", null))
271         return;
272 }
273
274 static void
275 main_install(void)
276 {
277     int part, ret;
278     const char *name;
279     char *items1[] =
280     {
281         "1", "Harddisk Install",
282         "2", "Network Install(NFS)",
283         "3", "Premounted on /source"
284     };
285
286     if (num_linux == 0) {
287         /* XXX */
288         return;
289     }
290     if ((part = select_install_partition()) <= -1)
291         return;
292     install_partition = name = partitions[part].name;
293     if (my_system("mke2fs %s %s", name, null))
294         return;
295     if (my_system("mount -t ext2 %s /install %s", name, null))
296         return;
297     ret = dialog_menu("Choose install medium",
298                       "\\nPlease say from where you want to install.\\n",
299                       12, 62, 3, 3, items1);
300     dialog_clear();
301     switch (ret) {
302     case 0:
303         install_harddisk();
304         break;
305     case 1:
306         install_nfs();
307         break;
308     case 2:
309         install_premounted();
310         break;
311     case -2:                    /* cancel */
312     case -1:
313         break;                  /* esc */
314     }
315     if (my_system("umount /install %s", null))
316         return;
317 }
318
319 int
320 main(int argc, char **argv)
321 {
322     int stop = 0;
323     int ret;
324     char *items1[] =
325     {
326         "1", "Display a help text",
327         "2", "Start an installation",
328         "3", "Exit to the shell"
329     };
330
331     progname = argv[0];
332
333     read_partitions();
334     if (num_linux == 0) {
335         printf("\n\nPlease start \"fdisk\" or \"cfdisk\" and create a"
336                "\nnative Linux-partition to install Linux on.\n\n");
337         exit(1);
338     }
339
340     init_dialog();
341
342     while (!stop) {
343         ret = dialog_menu("Linux Install Utility",
344                           "\\nCopyright (C) 1995 Florian La Roche\\n"
345                           "\\nPre-Alpha version, be careful, read the doc!!!"
346                           "\\nemail: florian@jurix.jura.uni-sb.de, "
347                           "flla@stud.uni-sb.de\\n",
348                           15, 64, 3, 3, items1);
349         dialog_clear();
350         switch (ret) {
351         case 0:
352             ret = dialog_textbox("Help Text",
353                                  "setup.help", 20, 70);
354             dialog_clear();
355             break;
356         case 1:
357             main_install();
358             break;
359         case 2:
360             stop = 1;
361             break;
362         case -2:                /* cancel */
363         case -1:
364             stop = 1;           /* esc */
365         }
366     }
367     end_dialog();
368     printf("\nExecute \"reboot\" to restart your computer...\n");
369
370     exit(0);
371 }