Subversion Repositories SvarDOS

Rev

Rev 625 | Rev 817 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
28 mv_fox 1
/*
190 mateuszvis 2
 * SVARDOS INSTALL PROGRAM
206 mateuszvis 3
 *
190 mateuszvis 4
 * PUBLISHED UNDER THE TERMS OF THE MIT LICENSE
42 mv_fox 5
 *
624 mateuszvis 6
 * COPYRIGHT (C) 2016-2022 MATEUSZ VISTE, ALL RIGHTS RESERVED.
94 mv_fox 7
 *
190 mateuszvis 8
 * Permission is hereby granted, free of charge, to any person obtaining a
9
 * copy of this software and associated documentation files (the "Software"),
10
 * to deal in the Software without restriction, including without limitation
11
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12
 * and/or sell copies of the Software, and to permit persons to whom the
13
 * Software is furnished to do so, subject to the following conditions:
94 mv_fox 14
 *
190 mateuszvis 15
 * The above copyright notice and this permission notice shall be included in
16
 * all copies or substantial portions of the Software.
94 mv_fox 17
 *
190 mateuszvis 18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24
 * DEALINGS IN THE SOFTWARE.
94 mv_fox 25
 *
190 mateuszvis 26
 * http://svardos.osdn.io
28 mv_fox 27
 */
28
 
29
#include <dos.h>
30 mv_fox 30
#include <direct.h>  /* mkdir() */
28 mv_fox 31
#include <stdio.h>   /* printf() and friends */
32
#include <stdlib.h>  /* system() */
33
#include <string.h>  /* memcpy() */
34
#include <unistd.h>
42 mv_fox 35
 
624 mateuszvis 36
#include "svarlang.lib\svarlang.h"
42 mv_fox 37
 
28 mv_fox 38
#include "input.h"
39
#include "video.h"
40
 
67 mv_fox 41
/* keyboard layouts and locales */
42
#include "keylay.h"
43
#include "keyoff.h"
42 mv_fox 44
 
29 mv_fox 45
/* color scheme (color, mono) */
46
static unsigned short COLOR_TITLEBAR[2] = {0x7000,0x7000};
47
static unsigned short COLOR_BODY[2] = {0x1700,0x0700};
48
static unsigned short COLOR_SELECT[2] = {0x7000,0x7000};
49
static unsigned short COLOR_SELECTCUR[2] = {0x1F00,0x0700};
28 mv_fox 50
 
29 mv_fox 51
/* mono flag */
52
static int mono = 0;
28 mv_fox 53
 
190 mateuszvis 54
/* how much disk space does SvarDOS require (in MiB) */
55
#define SVARDOS_DISK_REQ 8
28 mv_fox 56
 
73 mv_fox 57
/* menu screens can output only one of these: */
58
#define MENUNEXT 0
59
#define MENUPREV -1
60
#define MENUQUIT -2
61
 
67 mv_fox 62
/* a convenience 'function' used for debugging */
63
#define DBG(x) { video_putstringfix(24, 0, 0x4F00u, x, 80); }
47 mv_fox 64
 
67 mv_fox 65
struct slocales {
66
  char lang[4];
624 mateuszvis 67
  const char *keybcode;
67 mv_fox 68
  unsigned int codepage;
69
  int egafile;
70
  int keybfile;
71
  int keyboff;
72
  int keyblen;
96 mv_fox 73
  unsigned int keybid;
67 mv_fox 74
};
75
 
76
 
28 mv_fox 77
/* reboot the computer */
78
static void reboot(void) {
79
  void ((far *bootroutine)()) = (void (far *)()) 0xFFFF0000L;
80
  int far *rstaddr = (int far *)0x00400072L; /* BIOS boot flag is at 0040:0072 */
81
  *rstaddr = 0x1234; /* 0x1234 = warm boot, 0 = cold boot */
82
  (*bootroutine)(); /* jump to the BIOS reboot routine at FFFF:0000 */
83
}
84
 
42 mv_fox 85
 
56 mv_fox 86
/* outputs a string to screen with taking care of word wrapping. returns amount of lines. */
624 mateuszvis 87
static int putstringwrap(int y, int x, unsigned short attr, const char *s) {
56 mv_fox 88
  int linew, lincount;
89
  linew = 80;
90
  if (x >= 0) linew -= (x << 1);
91
 
92
  for (lincount = 1; y+lincount < 25; lincount++) {
93
    int i, len = linew;
94
    for (i = 0; i <= linew; i++) {
95
      if (s[i] == ' ') len = i;
96
      if (s[i] == '\n') {
97
        len = i;
98
        break;
99
      }
100
      if (s[i] == 0) {
101
        len = i;
102
        break;
103
      }
104
    }
105
    video_putstring(y++, x, attr, s, len);
106
    s += len;
107
    if (*s == 0) break;
108
    s += 1; /* skip the whitespace char */
109
  }
110
  return(lincount);
111
}
112
 
113
 
114
/* an NLS wrapper around video_putstring(), also performs line wrapping when
115
 * needed. returns the amount of lines that were output */
624 mateuszvis 116
static int putstringnls(int y, int x, unsigned short attr, int nlsmaj, int nlsmin) {
117
  const char *s = svarlang_str(nlsmaj, nlsmin);
118
  if (s == NULL) s = "";
56 mv_fox 119
  return(putstringwrap(y, x, attr, s));
42 mv_fox 120
}
121
 
122
 
280 mateuszvis 123
/* copy file f1 to f2 using buff as a buffer of buffsz bytes. f2 will be overwritten if it
124
 * exists already! returns 0 on success. */
125
static int fcopy(const char *f2, const char *f1, void *buff, size_t buffsz) {
126
  FILE *fd1, *fd2;
127
  size_t sz;
128
  int res = -1; /* assume failure */
129
 
130
  /* open files */
131
  fd1 = fopen(f1, "rb");
132
  fd2 = fopen(f2, "wb");
133
  if ((fd1 == NULL) || (fd2 == NULL)) goto QUIT;
134
 
135
  /* copy data */
136
  for (;;) {
137
    sz = fread(buff, 1, buffsz, fd1);
138
    if (sz == 0) {
139
      if (feof(fd1) != 0) break;
140
      goto QUIT;
141
    }
142
    if (fwrite(buff, 1, sz, fd2) != sz) goto QUIT;
143
  }
144
 
145
  res = 0; /* success */
146
 
147
  QUIT:
148
  if (fd1 != NULL) fclose(fd1);
149
  if (fd2 != NULL) fclose(fd2);
150
  return(res);
151
}
152
 
153
 
624 mateuszvis 154
static int menuselect(int ypos, int xpos, int height, const char **list, int listlen) {
28 mv_fox 155
  int i, offset = 0, res = 0, count, width = 0;
67 mv_fox 156
  /* count how many positions there is, and check their width */
157
  for (count = 0; (list[count] != NULL) && (count != listlen); count++) {
28 mv_fox 158
    int len = strlen(list[count]);
159
    if (len > width) width = len;
160
  }
161
 
162
  /* if xpos negative, means 'center out' */
163
  if (xpos < 0) xpos = 39 - (width >> 1);
164
 
29 mv_fox 165
  video_putchar(ypos, xpos+width+2, COLOR_SELECT[mono], 0xBF);         /*       \ */
166
  video_putchar(ypos, xpos-1, COLOR_SELECT[mono], 0xDA);               /*  /      */
167
  video_putchar(ypos+height-1, xpos-1, COLOR_SELECT[mono], 0xC0);      /*  \      */
168
  video_putchar(ypos+height-1, xpos+width+2, COLOR_SELECT[mono], 0xD9);/*      /  */
169
  video_putcharmulti(ypos, xpos, COLOR_SELECT[mono], 0xC4, width + 2, 1);
170
  video_putcharmulti(ypos+height-1, xpos, COLOR_SELECT[mono], 0xC4, width + 2, 1);
171
  video_putcharmulti(ypos+1, xpos-1, COLOR_SELECT[mono], 0xB3, height - 2, 80);
172
  video_putcharmulti(ypos+1, xpos+width+2, COLOR_SELECT[mono], 0xB3, height - 2, 80);
28 mv_fox 173
 
174
  for (;;) {
175
    int key;
176
    /* list of selectable items */
177
    for (i = 0; i < height - 2; i++) {
178
      if (i + offset == res) {
29 mv_fox 179
        video_putchar(ypos + 1 + i, xpos, COLOR_SELECTCUR[mono], 16);
180
        video_putchar(ypos + 1 + i, xpos+width+1, COLOR_SELECTCUR[mono], 17);
28 mv_fox 181
        video_movecursor(ypos + 1 + i, xpos);
29 mv_fox 182
        video_putstringfix(ypos + 1 + i, xpos+1, COLOR_SELECTCUR[mono], list[i + offset], width);
28 mv_fox 183
      } else if (i + offset < count) {
29 mv_fox 184
        video_putchar(ypos + 1 + i, xpos, COLOR_SELECT[mono], ' ');
185
        video_putchar(ypos + 1 + i, xpos+width+1, COLOR_SELECT[mono], ' ');
186
        video_putstringfix(ypos + 1 + i, xpos+1, COLOR_SELECT[mono], list[i + offset], width);
28 mv_fox 187
      } else {
29 mv_fox 188
        video_putcharmulti(ypos + 1 + i, xpos, COLOR_SELECT[mono], ' ', width+2, 1);
28 mv_fox 189
      }
190
    }
191
    key = input_getkey();
192
    if (key == 0x0D) { /* ENTER */
193
      return(res);
194
    } else if (key == 0x148) { /* up */
33 mv_fox 195
      if (res > 0) {
196
        res--;
197
        if (res < offset) offset = res;
198
      }
28 mv_fox 199
    } else if (key == 0x150) { /* down */
33 mv_fox 200
      if (res+1 < count) {
201
        res++;
202
        if (res > offset + height - 3) offset = res - (height - 3);
203
      }
204
    } else if (key == 0x147) { /* home */
205
      res = 0;
206
      offset = 0;
207
    } else if (key == 0x14F) { /* end */
208
      res = count - 1;
209
      if (res > offset + height - 3) offset = res - (height - 3);
28 mv_fox 210
    } else if (key == 0x1B) {  /* ESC */
211
      return(-1);
78 mv_fox 212
    }/* else {
33 mv_fox 213
      char buf[8];
55 mv_fox 214
      snprintf(buf, sizeof(buf), "0x%02X ", key);
56 mv_fox 215
      video_putstring(1, 0, COLOR_BODY[mono], buf, -1);
78 mv_fox 216
    }*/
28 mv_fox 217
  }
218
}
219
 
79 mv_fox 220
static void newscreen(int statusbartype) {
624 mateuszvis 221
  const char *msg;
222
  msg = svarlang_strid(0x00); /* "SVARDOS INSTALLATION" */
81 mv_fox 223
  video_putcharmulti(0, 0, COLOR_TITLEBAR[mono], ' ', 80, 1);
79 mv_fox 224
  video_putstring(0, 40 - (strlen(msg) >> 1), COLOR_TITLEBAR[mono], msg, -1);
81 mv_fox 225
  video_clear(COLOR_BODY[mono], 80, -80);
79 mv_fox 226
  switch (statusbartype) {
227
    case 1:
624 mateuszvis 228
      msg = svarlang_strid(0x000B); /* "Up/Down = Select entry | Enter = Validate your choice | ESC = Quit to DOS" */
79 mv_fox 229
      break;
230
    case 2:
624 mateuszvis 231
      msg = svarlang_strid(0x0005); /* "Press any key..." */
79 mv_fox 232
      break;
233
    case 3:
234
      msg = "";
235
      break;
236
    default:
624 mateuszvis 237
      msg = svarlang_strid(0x000A); /* "Up/Down = Select entry | Enter = Validate your choice | ESC = Previous screen" */
79 mv_fox 238
      break;
239
  }
240
  video_putchar(24, 0, COLOR_TITLEBAR[mono], ' ');
241
  video_putstringfix(24, 1, COLOR_TITLEBAR[mono], msg, 79);
36 mv_fox 242
  video_movecursor(25,0);
28 mv_fox 243
}
244
 
96 mv_fox 245
/* fills a slocales struct accordingly to the value of its keyboff member */
246
static void kblay2slocal(struct slocales *locales) {
624 mateuszvis 247
  const char *m;
96 mv_fox 248
  for (m = kblayouts[locales->keyboff]; *m != 0; m++); /* skip layout name */
249
  m++;
250
  /* skip keyb code and copy it to locales.keybcode */
251
  locales->keybcode = m;
252
  for (; *m != 0; m++);
253
  /* */
254
  locales->codepage = ((unsigned short)m[1] << 8) | m[2];
255
  locales->egafile = m[3];
256
  locales->keybfile = m[4];
257
  locales->keybid = ((unsigned short)m[5] << 8) | m[6];
258
}
259
 
67 mv_fox 260
static int selectlang(struct slocales *locales) {
261
  int choice, x;
624 mateuszvis 262
  const char *msg;
263
  const char *langlist[] = {
67 mv_fox 264
    "English",
265
    "French",
133 mv_fox 266
    "German",
119 mv_fox 267
    "Italian",
67 mv_fox 268
    "Polish",
116 mv_fox 269
    "Russian",
123 mv_fox 270
    "Slovene",
128 mv_fox 271
    "Swedish",
67 mv_fox 272
    "Turkish",
28 mv_fox 273
    NULL
274
  };
275
 
79 mv_fox 276
  newscreen(1);
624 mateuszvis 277
  msg = svarlang_strid(0x0100); /* "Welcome to SvarDOS" */
42 mv_fox 278
  x = 40 - (strlen(msg) >> 1);
56 mv_fox 279
  video_putstring(4, x, COLOR_BODY[mono], msg, -1);
42 mv_fox 280
  video_putcharmulti(5, x, COLOR_BODY[mono], '=', strlen(msg), 1);
624 mateuszvis 281
  putstringnls(8, -1, COLOR_BODY[mono], 1, 1); /* "Please select your language from the list below:" */
133 mv_fox 282
  choice = menuselect(11, -1, 11, langlist, -1);
73 mv_fox 283
  if (choice < 0) return(MENUPREV);
67 mv_fox 284
  /* populate locales with default values */
285
  memset(locales, 0, sizeof(struct slocales));
286
  switch (choice) {
287
    case 1:
288
      strcpy(locales->lang, "FR");
289
      locales->keyboff = OFFLOC_FR;
290
      locales->keyblen = OFFLEN_FR;
291
      break;
292
    case 2:
133 mv_fox 293
      strcpy(locales->lang, "DE");
294
      locales->keyboff = OFFLOC_DE;
295
      locales->keyblen = OFFLEN_DE;
296
      break;
297
    case 3:
119 mv_fox 298
      strcpy(locales->lang, "IT");
299
      locales->keyboff = OFFLOC_IT;
300
      locales->keyblen = OFFLEN_IT;
301
      break;
133 mv_fox 302
    case 4:
67 mv_fox 303
      strcpy(locales->lang, "PL");
304
      locales->keyboff = OFFLOC_PL;
305
      locales->keyblen = OFFLEN_PL;
306
      break;
133 mv_fox 307
    case 5:
116 mv_fox 308
      strcpy(locales->lang, "RU");
309
      locales->keyboff = OFFLOC_RU;
310
      locales->keyblen = OFFLEN_RU;
311
      break;
133 mv_fox 312
    case 6:
123 mv_fox 313
      strcpy(locales->lang, "SI");
314
      locales->keyboff = OFFLOC_SI;
315
      locales->keyblen = OFFLEN_SI;
316
      break;
133 mv_fox 317
    case 7:
128 mv_fox 318
      strcpy(locales->lang, "SV");
319
      locales->keyboff = OFFLOC_SV;
320
      locales->keyblen = OFFLEN_SV;
321
      break;
133 mv_fox 322
    case 8:
67 mv_fox 323
      strcpy(locales->lang, "TR");
324
      locales->keyboff = OFFLOC_TR;
325
      locales->keyblen = OFFLEN_TR;
326
      break;
327
    default:
328
      strcpy(locales->lang, "EN");
329
      locales->keyboff = 0;
330
      locales->keyblen = OFFCOUNT;
331
      break;
332
  }
96 mv_fox 333
  /* populate the slocales struct accordingly to the keyboff member */
334
  kblay2slocal(locales);
67 mv_fox 335
  /* */
73 mv_fox 336
  return(MENUNEXT);
28 mv_fox 337
}
338
 
339
 
67 mv_fox 340
static int selectkeyb(struct slocales *locales) {
96 mv_fox 341
  int menuheight, choice;
342
  if (locales->keyblen == 1) return(MENUNEXT); /* do not ask for keyboard layout if only one is available for given language */
79 mv_fox 343
  newscreen(0);
624 mateuszvis 344
  putstringnls(5, 1, COLOR_BODY[mono], 1, 5); /* "SvarDOS supports different keyboard layouts */
96 mv_fox 345
  menuheight = locales->keyblen + 2;
67 mv_fox 346
  if (menuheight > 13) menuheight = 13;
96 mv_fox 347
  choice = menuselect(10, -1, menuheight, &(kblayouts[locales->keyboff]), locales->keyblen);
348
  if (choice < 0) return(MENUPREV);
349
  /* (re)load the keyboard layout & codepage setup */
350
  locales->keyboff += choice;
351
  kblay2slocal(locales);
73 mv_fox 352
  return(MENUNEXT);
67 mv_fox 353
}
354
 
355
 
28 mv_fox 356
/* returns 0 if installation must proceed, non-zero otherwise */
357
static int welcomescreen(void) {
73 mv_fox 358
  int c;
624 mateuszvis 359
  const char *choice[3];
360
  choice[0] = svarlang_strid(0x0001);
361
  choice[1] = svarlang_strid(0x0002);
362
  choice[2] = NULL;
79 mv_fox 363
  newscreen(0);
624 mateuszvis 364
  putstringnls(4, 1, COLOR_BODY[mono], 2, 0); /* "You are about to install SvarDOS */
73 mv_fox 365
  c = menuselect(13, -1, 4, choice, -1);
366
  if (c < 0) return(MENUPREV);
367
  if (c == 0) return(MENUNEXT);
368
  return(MENUQUIT);
28 mv_fox 369
}
370
 
371
 
33 mv_fox 372
/* returns 1 if drive is removable, 0 if not, -1 on error */
373
static int isdriveremovable(int drv) {
28 mv_fox 374
  union REGS r;
33 mv_fox 375
  r.x.ax = 0x4408;
376
  r.h.bl = drv;
28 mv_fox 377
  int86(0x21, &r, &r);
33 mv_fox 378
  /* CF set on error, AX set to 0 if removable, 1 if fixed */
379
  if (r.x.cflag != 0) return(-1);
380
  if (r.x.ax == 0) return(1);
381
  return(0);
28 mv_fox 382
}
383
 
384
 
35 mv_fox 385
/* returns total disk space of drive drv (in MiB, max 2048), or -1 if drive invalid */
386
static int disksize(int drv) {
28 mv_fox 387
  long res;
388
  union REGS r;
389
  r.h.ah = 0x36; /* DOS 2+ get free disk space */
312 mateuszvis 390
  r.h.dl = drv;  /* A=1, B=2, etc */
28 mv_fox 391
  int86(0x21, &r, &r);
392
  if (r.x.ax == 0xffffu) return(-1); /* AX set to FFFFh if drive invalid */
49 mv_fox 393
  res = r.x.ax;  /* sectors per cluster */
394
  res *= r.x.dx; /* dx contains total clusters, bx contains free clusters */
395
  res *= r.x.cx; /* bytes per sector */
396
  res >>= 20;    /* convert bytes to MiB */
397
  return(res);
35 mv_fox 398
}
399
 
400
 
401
/* returns 0 if disk is empty, non-zero otherwise */
402
static int diskempty(int drv) {
403
  unsigned int rc;
404
  int res;
405
  char buff[8];
406
  struct find_t fileinfo;
55 mv_fox 407
  snprintf(buff, sizeof(buff), "%c:\\*.*", 'A' + drv - 1);
35 mv_fox 408
  rc = _dos_findfirst(buff, _A_NORMAL | _A_SUBDIR | _A_HIDDEN | _A_SYSTEM, &fileinfo);
409
  if (rc == 0) {
410
    res = 1; /* call successfull means disk is not empty */
28 mv_fox 411
  } else {
35 mv_fox 412
    res = 0;
28 mv_fox 413
  }
35 mv_fox 414
  /* _dos_findclose(&fileinfo); */ /* apparently required only on OS/2 */
28 mv_fox 415
  return(res);
416
}
417
 
280 mateuszvis 418
#ifdef DEADCODE
200 mateuszvis 419
/* set new DOS "current drive" to drv ('A', 'B', etc). returns 0 on success */
420
static int set_cur_drive(char drv) {
421
  union REGS r;
422
  if ((drv < 'A') || (drv > 'Z')) return(-1);
423
  r.h.ah = 0x0E; /* DOS 1+ SELECT DEFAULT DRIVE */
424
  r.h.dl = drv - 'A';
425
  int86(0x21, &r, &r);
426
  if (r.h.al < drv - 'A') return(-1);
427
  return(0);
428
}
280 mateuszvis 429
#endif
200 mateuszvis 430
 
310 mateuszvis 431
 
432
/* get the DOS "current drive" (0=A:, 1=B:, etc) */
433
static int get_cur_drive(void) {
434
  union REGS r;
435
  r.h.ah = 0x19; /* DOS 1+ GET CURRENT DEFAULT DRIVE */
436
  int86(0x21, &r, &r);
437
  return(r.h.al);
438
}
439
 
440
 
200 mateuszvis 441
/* returns 0 if file exists, non-zero otherwise */
442
static int fileexists(const char *fname) {
443
  FILE *fd;
444
  fd = fopen(fname, "rb");
445
  if (fd == NULL) return(-1);
446
  fclose(fd);
447
  return(0);
448
}
449
 
450
 
310 mateuszvis 451
static int preparedrive(char sourcedrv) {
33 mv_fox 452
  int driveremovable;
310 mateuszvis 453
  int selecteddrive = 3; /* default to 'C:' */
36 mv_fox 454
  int cselecteddrive;
35 mv_fox 455
  int ds;
73 mv_fox 456
  int choice;
56 mv_fox 457
  char buff[1024];
312 mateuszvis 458
  int driveid = 1; /* fdisk runs on first drive (unless USB boot) */
459
  if (selecteddrive == get_cur_drive() + 1) { /* get_cur_drive() returns 0-based values (A=0) while selecteddrive is 1-based (A=1) */
460
    selecteddrive = 4; /* use D: if install is run from C: (typically because it was booted from USB?) */
461
    driveid = 2; /* primary drive is the emulated USB storage */
462
  }
36 mv_fox 463
  cselecteddrive = 'A' + selecteddrive - 1;
28 mv_fox 464
  for (;;) {
33 mv_fox 465
    driveremovable = isdriveremovable(selecteddrive);
466
    if (driveremovable < 0) {
624 mateuszvis 467
      const char *list[4];
79 mv_fox 468
      newscreen(0);
624 mateuszvis 469
      list[0] = svarlang_str(0, 3); /* Create a partition automatically */
470
      list[1] = svarlang_str(0, 4); /* Run the FDISK tool */
471
      list[2] = svarlang_str(0, 2); /* Quit to DOS */
472
      list[3] = NULL;
473
      snprintf(buff, sizeof(buff), svarlang_strid(0x0300), cselecteddrive, SVARDOS_DISK_REQ); /* "ERROR: Drive %c: could not be found. Note, that SvarDOS requires at least %d MiB of available disk space */
555 mateuszvis 474
      switch (menuselect(6 + putstringwrap(4, 1, COLOR_BODY[mono], buff), -1, 5, list, -1)) {
33 mv_fox 475
        case 0:
312 mateuszvis 476
          sprintf(buff, "FDISK /AUTO %d", driveid);
477
          system(buff);
33 mv_fox 478
          break;
479
        case 1:
81 mv_fox 480
          video_clear(0x0700, 0, 0);
33 mv_fox 481
          video_movecursor(0, 0);
312 mateuszvis 482
          sprintf(buff, "FDISK %d", driveid);
483
          system(buff);
33 mv_fox 484
          break;
73 mv_fox 485
        case 2:
486
          return(MENUQUIT);
56 mv_fox 487
        default:
33 mv_fox 488
          return(-1);
489
      }
113 mv_fox 490
      /* write a temporary MBR which only skips the drive (in case BIOS would
491
       * try to boot off the not-yet-ready C: disk) */
312 mateuszvis 492
      sprintf(buff, "FDISK /AMBR %d", driveid);
493
      system(buff); /* writes BOOT.MBR into actual MBR */
79 mv_fox 494
      newscreen(2);
624 mateuszvis 495
      putstringnls(10, 10, COLOR_BODY[mono], 3, 1); /* "Your computer will reboot now." */
496
      putstringnls(12, 10, COLOR_BODY[mono], 0, 5); /* "Press any key..." */
33 mv_fox 497
      input_getkey();
28 mv_fox 498
      reboot();
73 mv_fox 499
      return(MENUQUIT);
33 mv_fox 500
    } else if (driveremovable > 0) {
79 mv_fox 501
      newscreen(2);
624 mateuszvis 502
      snprintf(buff, sizeof(buff), svarlang_strid(0x0302), cselecteddrive); /* "ERROR: Drive %c: is a removable device */
61 mv_fox 503
      video_putstring(9, 1, COLOR_BODY[mono], buff, -1);
624 mateuszvis 504
      putstringnls(11, 2, COLOR_BODY[mono], 0, 5); /* "Press any key..." */
73 mv_fox 505
      return(MENUQUIT);
28 mv_fox 506
    }
33 mv_fox 507
    /* if not formatted, propose to format it right away (try to create a directory) */
55 mv_fox 508
    snprintf(buff, sizeof(buff), "%c:\\SVWRTEST.123", cselecteddrive);
53 mv_fox 509
    if (mkdir(buff) == 0) {
510
      rmdir(buff);
511
    } else {
624 mateuszvis 512
      const char *list[3];
79 mv_fox 513
      newscreen(0);
624 mateuszvis 514
      snprintf(buff, sizeof(buff), svarlang_str(3, 3), cselecteddrive); /* "ERROR: Drive %c: seems to be unformated. Do you wish to format it?") */
61 mv_fox 515
      video_putstring(7, 1, COLOR_BODY[mono], buff, -1);
556 mateuszvis 516
 
624 mateuszvis 517
      snprintf(buff, sizeof(buff), svarlang_strid(0x0007), cselecteddrive); /* "Format drive %c:" */
556 mateuszvis 518
      list[0] = buff;
624 mateuszvis 519
      list[1] = svarlang_strid(0x0002); /* "Quit to DOS" */
556 mateuszvis 520
      list[2] = NULL;
521
 
73 mv_fox 522
      choice = menuselect(12, -1, 4, list, -1);
523
      if (choice < 0) return(MENUPREV);
524
      if (choice == 1) return(MENUQUIT);
81 mv_fox 525
      video_clear(0x0700, 0, 0);
28 mv_fox 526
      video_movecursor(0, 0);
190 mateuszvis 527
      snprintf(buff, sizeof(buff), "FORMAT %c: /Q /U /Z:seriously /V:SVARDOS", cselecteddrive);
36 mv_fox 528
      system(buff);
28 mv_fox 529
      continue;
530
    }
33 mv_fox 531
    /* check total disk space */
35 mv_fox 532
    ds = disksize(selecteddrive);
190 mateuszvis 533
    if (ds < SVARDOS_DISK_REQ) {
56 mv_fox 534
      int y = 9;
79 mv_fox 535
      newscreen(2);
624 mateuszvis 536
      snprintf(buff, sizeof(buff), svarlang_strid(0x0304), cselecteddrive, SVARDOS_DISK_REQ); /* "ERROR: Drive %c: is not big enough! SvarDOS requires a disk of at least %d MiB." */
61 mv_fox 537
      y += putstringwrap(y, 1, COLOR_BODY[mono], buff);
624 mateuszvis 538
      putstringnls(++y, 1, COLOR_BODY[mono], 0, 5); /* "Press any key..." */
28 mv_fox 539
      input_getkey();
73 mv_fox 540
      return(MENUQUIT);
28 mv_fox 541
    }
542
    /* is the disk empty? */
79 mv_fox 543
    newscreen(0);
35 mv_fox 544
    if (diskempty(selecteddrive) != 0) {
624 mateuszvis 545
      const char *list[3];
65 mv_fox 546
      int y = 6;
624 mateuszvis 547
      snprintf(buff, sizeof(buff), svarlang_strid(0x0305), cselecteddrive); /* "ERROR: Drive %c: not empty" */
65 mv_fox 548
      y += putstringwrap(y, 1, COLOR_BODY[mono], buff);
556 mateuszvis 549
 
624 mateuszvis 550
      snprintf(buff, sizeof(buff), svarlang_strid(0x0007), cselecteddrive); /* "Format drive %c:" */
556 mateuszvis 551
      list[0] = buff;
624 mateuszvis 552
      list[1] = svarlang_strid(0x0002); /* "Quit to DOS" */
556 mateuszvis 553
      list[2] = NULL;
554
 
73 mv_fox 555
      choice = menuselect(++y, -1, 4, list, -1);
556
      if (choice < 0) return(MENUPREV);
557
      if (choice == 1) return(MENUQUIT);
81 mv_fox 558
      video_clear(0x0700, 0, 0);
28 mv_fox 559
      video_movecursor(0, 0);
190 mateuszvis 560
      snprintf(buff, sizeof(buff), "FORMAT %c: /Q /U /Z:seriously /V:SVARDOS", cselecteddrive);
42 mv_fox 561
      system(buff);
28 mv_fox 562
      continue;
563
    } else {
564
      /* final confirmation */
624 mateuszvis 565
      const char *list[3];
566
      list[0] = svarlang_strid(0x0001); /* Install SvarDOS */
567
      list[1] = svarlang_strid(0x0002); /* Quit to DOS */
568
      list[2] = NULL;
569
      snprintf(buff, sizeof(buff), svarlang_strid(0x0306), cselecteddrive); /* "The installation of SvarDOS to %c: is about to begin." */
56 mv_fox 570
      video_putstring(7, -1, COLOR_BODY[mono], buff, -1);
73 mv_fox 571
      choice = menuselect(10, -1, 4, list, -1);
572
      if (choice < 0) return(MENUPREV);
573
      if (choice == 1) return(MENUQUIT);
310 mateuszvis 574
      snprintf(buff, sizeof(buff), "SYS %c: %c: > NUL", sourcedrv, cselecteddrive);
36 mv_fox 575
      system(buff);
312 mateuszvis 576
      sprintf(buff, "FDISK /MBR %d", driveid);
577
      system(buff);
55 mv_fox 578
      snprintf(buff, sizeof(buff), "%c:\\TEMP", cselecteddrive);
36 mv_fox 579
      mkdir(buff);
580
      return(cselecteddrive);
28 mv_fox 581
    }
582
  }
583
}
584
 
585
 
280 mateuszvis 586
/* generates locales-related configurations and writes them to file (this
587
 * is used to compute autoexec.bat content) */
588
static void genlocalesconf(FILE *fd, const struct slocales *locales) {
589
  if (locales == NULL) return;
590
 
591
  fprintf(fd, "SET LANG=%s\r\n", locales->lang);
592
 
593
  if (locales->egafile > 0) {
594
    fprintf(fd, "DISPLAY CON=(EGA,,1)\r\n");
595
    if (locales->egafile == 1) {
596
      fprintf(fd, "MODE CON CP PREPARE=((%u) %%DOSDIR%%\\CPI\\EGA.CPX)\r\n", locales->codepage);
597
    } else {
598
      fprintf(fd, "MODE CON CP PREPARE=((%u) %%DOSDIR%%\\CPI\\EGA%d.CPX)\r\n", locales->codepage, locales->egafile);
599
    }
600
    fprintf(fd, "MODE CON CP SELECT=%u\r\n", locales->codepage);
601
  }
602
 
603
  if (locales->keybfile > 0) {
604
    fprintf(fd, "KEYB %s,%d,%%DOSDIR%%\\BIN\\", locales->keybcode, locales->codepage);
605
    if (locales->keybfile == 1) {
606
      fprintf(fd, "KEYBOARD.SYS");
607
    } else {
608
      fprintf(fd, "KEYBRD%d.SYS", locales->keybfile);
609
    }
610
    if (locales->keybid != 0) fprintf(fd, " /ID:%d", locales->keybid);
611
    fprintf(fd, "\r\n");
612
  }
613
}
614
 
615
 
616
static void bootfilesgen(char targetdrv, const struct slocales *locales) {
28 mv_fox 617
  char buff[128];
618
  FILE *fd;
53 mv_fox 619
  /*** CONFIG.SYS ***/
280 mateuszvis 620
  snprintf(buff, sizeof(buff), "%c:\\TEMP\\CONFIG.SYS", targetdrv);
53 mv_fox 621
  fd = fopen(buff, "wb");
622
  if (fd == NULL) return;
101 mv_fox 623
  fprintf(fd, "DOS=UMB,HIGH\r\n"
624
              "LASTDRIVE=Z\r\n"
625
              "FILES=50\r\n");
312 mateuszvis 626
  fprintf(fd, "DEVICE=C:\\SVARDOS\\BIN\\HIMEMX.EXE\r\n");
77 mv_fox 627
  if (strcmp(locales->lang, "EN") == 0) {
95 mv_fox 628
    strcpy(buff, "COMMAND");
77 mv_fox 629
  } else {
630
    snprintf(buff, sizeof(buff), "CMD-%s", locales->lang);
631
  }
280 mateuszvis 632
  fprintf(fd, "SHELLHIGH=C:\\SVARDOS\\BIN\\%s.COM /E:512 /P\r\n", buff);
625 mateuszvis 633
  fprintf(fd, "REM COUNTRY=001,%u,C:\\SVARDOS\\CFG\\COUNTRY.SYS\r\n", locales->codepage);
280 mateuszvis 634
  fprintf(fd, "REM DEVICE=C:\\DRIVERS\\UDVD2\\UDVD2.SYS /D:SVCD0001 /H\r\n");
53 mv_fox 635
  fclose(fd);
28 mv_fox 636
  /*** AUTOEXEC.BAT ***/
280 mateuszvis 637
  snprintf(buff, sizeof(buff), "%c:\\TEMP\\AUTOEXEC.BAT", targetdrv);
28 mv_fox 638
  fd = fopen(buff, "wb");
639
  if (fd == NULL) return;
640
  fprintf(fd, "@ECHO OFF\r\n");
280 mateuszvis 641
  fprintf(fd, "SET TEMP=C:\\TEMP\r\n");
642
  fprintf(fd, "SET DOSDIR=C:\\SVARDOS\r\n");
49 mv_fox 643
  fprintf(fd, "SET NLSPATH=%%DOSDIR%%\\NLS\r\n");
53 mv_fox 644
  fprintf(fd, "SET DIRCMD=/OGNE/P/4\r\n");
303 mateuszvis 645
  fprintf(fd, "SET WATTCP.CFG=%%DOSDIR%%\\CFG\r\n");
280 mateuszvis 646
  fprintf(fd, "PATH %%DOSDIR%%\\BIN\r\n");
28 mv_fox 647
  fprintf(fd, "PROMPT $P$G\r\n");
30 mv_fox 648
  fprintf(fd, "ALIAS REBOOT=FDAPM COLDBOOT\r\n");
649
  fprintf(fd, "ALIAS HALT=FDAPM POWEROFF\r\n");
56 mv_fox 650
  fprintf(fd, "FDAPM APMDOS\r\n");
28 mv_fox 651
  fprintf(fd, "\r\n");
280 mateuszvis 652
  genlocalesconf(fd, locales);
49 mv_fox 653
  fprintf(fd, "\r\n");
280 mateuszvis 654
  fprintf(fd, "REM Uncomment the line below for CDROM support\r\n");
655
  fprintf(fd, "REM SHSUCDX /d:SVCD0001\r\n");
656
  fprintf(fd, "\r\n");
49 mv_fox 657
  fprintf(fd, "REM Uncomment the line below for automatic mouse support\r\n");
658
  fprintf(fd, "REM CTMOUSE\r\n");
659
  fprintf(fd, "\r\n");
53 mv_fox 660
  fprintf(fd, "ECHO.\r\n");
624 mateuszvis 661
  fprintf(fd, "ECHO %s\r\n", svarlang_strid(0x0600)); /* "Welcome to SvarDOS!" */
28 mv_fox 662
  fclose(fd);
200 mateuszvis 663
  /*** CREATE DIRECTORY FOR CONFIGURATION FILES ***/
277 mateuszvis 664
  snprintf(buff, sizeof(buff), "%c:\\SVARDOS", targetdrv);
200 mateuszvis 665
  mkdir(buff);
277 mateuszvis 666
  snprintf(buff, sizeof(buff), "%c:\\SVARDOS\\CFG", targetdrv);
53 mv_fox 667
  mkdir(buff);
277 mateuszvis 668
  /*** PKG.CFG ***/
669
  snprintf(buff, sizeof(buff), "%c:\\SVARDOS\\CFG\\PKG.CFG", targetdrv);
670
  fd = fopen(buff, "wb");
671
  if (fd == NULL) return;
672
  fprintf(fd, "# pkg config file - specifies locations where packages should be installed\r\n"
673
              "\r\n"
674
              "# Programs\r\n"
675
              "DIR PROGS C:\\\r\n"
676
              "\r\n"
677
              "# Games \r\n"
678
              "DIR GAMES C:\\\r\n"
679
              "\r\n"
680
              "# Drivers\r\n"
681
              "DIR DRIVERS C:\\DRIVERS\r\n"
682
              "\r\n"
683
              "# Development tools\r\n"
684
              "DIR DEVEL C:\\DEVEL\r\n");
685
  fclose(fd);
53 mv_fox 686
  /*** COUNTRY.SYS ***/
687
  /*** PICOTCP ***/
688
  /*** WATTCP ***/
303 mateuszvis 689
  snprintf(buff, sizeof(buff), "%c:\\SVARDOS\\CFG\\WATTCP.CFG", targetdrv);
690
  fd = fopen(buff, "wb");
691
  if (fd == NULL) return;
692
  fprintf(fd, "my_ip = dhcp\r\n"
693
              "#my_ip = 192.168.0.7\r\n"
694
              "#netmask = 255.255.255.0\r\n"
695
              "#nameserver = 192.168.0.1\r\n"
696
              "#nameserver = 192.168.0.2\r\n"
554 mateuszvis 697
              "#gateway = 192.168.0.1\r\n");
303 mateuszvis 698
  fclose(fd);
28 mv_fox 699
}
700
 
701
 
280 mateuszvis 702
static int installpackages(char targetdrv, char srcdrv, const struct slocales *locales) {
192 mateuszvis 703
  char pkglist[512];
30 mv_fox 704
  int i, pkglistlen;
192 mateuszvis 705
  size_t pkglistflen;
280 mateuszvis 706
  char buff[1024]; /* must be *at least* 1 sector big for efficient file copying */
707
  FILE *fd = NULL;
192 mateuszvis 708
  char *pkgptr;
79 mv_fox 709
  newscreen(3);
192 mateuszvis 710
  /* load pkg list */
711
  fd = fopen("install.lst", "rb");
712
  if (fd == NULL) {
713
    video_putstring(10, 30, COLOR_BODY[mono], "ERROR: INSTALL.LST NOT FOUND", -1);
714
    input_getkey();
715
    return(-1);
716
  }
717
  pkglistflen = fread(pkglist, 1, sizeof(pkglist), fd);
718
  fclose(fd);
719
  if (pkglistflen == sizeof(pkglist)) {
720
    video_putstring(10, 30, COLOR_BODY[mono], "ERROR: INSTALL.LST TOO LARGE", -1);
721
    input_getkey();
722
    return(-1);
723
  }
724
  pkglist[pkglistflen] = 0xff; /* mark the end of list */
725
  /* replace all \r and \n chars by 0 bytes, and count the number of packages */
726
  pkglistlen = 0;
727
  for (i = 0; i < pkglistflen; i++) {
728
    switch (pkglist[i]) {
729
      case '\n':
730
        pkglistlen++;
731
        /* FALLTHRU */
732
      case '\r':
733
        pkglist[i] = 0;
734
        break;
735
    }
736
  }
280 mateuszvis 737
  /* copy pkg.exe to the new drive, along with all packages */
738
  snprintf(buff, sizeof(buff), "%c:\\TEMP\\pkg.exe", targetdrv);
739
  snprintf(buff + 64, sizeof(buff) - 64, "%c:\\pkg.exe", srcdrv);
740
  fcopy(buff, buff + 64, buff, sizeof(buff));
741
 
742
  /* open the post-install autoexec.bat and prepare initial instructions */
743
  snprintf(buff, sizeof(buff), "%c:\\temp\\postinst.bat", targetdrv);
744
  fd = fopen(buff, "wb");
745
  if (fd == NULL) return(-1);
746
  fprintf(fd, "@ECHO OFF\r\n");
747
 
748
  /* copy packages */
192 mateuszvis 749
  pkgptr = pkglist;
750
  for (i = 0;; i++) {
751
    /* move forward to nearest entry or end of list */
752
    while (*pkgptr == 0) pkgptr++;
753
    if (*pkgptr == 0xff) break;
754
    /* install the package */
624 mateuszvis 755
    snprintf(buff, sizeof(buff), svarlang_strid(0x0400), i+1, pkglistlen, pkgptr); /* "Installing package %d/%d: %s" */
36 mv_fox 756
    strcat(buff, "       ");
192 mateuszvis 757
    video_putstringfix(10, 1, COLOR_BODY[mono], buff, sizeof(buff));
200 mateuszvis 758
    /* wait for new diskette if package not found */
700 mateusz.vi 759
    snprintf(buff, sizeof(buff), "%c:\\%s.svp", srcdrv, pkgptr);
200 mateuszvis 760
    while (fileexists(buff) != 0) {
624 mateuszvis 761
      putstringnls(12, 1, COLOR_BODY[mono], 4, 1); /* "INSERT THE DISK THAT CONTAINS THE REQUIRED FILE AND PRESS ANY KEY" */
200 mateuszvis 762
      input_getkey();
763
      video_putstringfix(12, 1, COLOR_BODY[mono], "", 80); /* erase the 'insert disk' message */
764
    }
280 mateuszvis 765
    /* proceed with package copy (buff contains the src filename already) */
700 mateusz.vi 766
    snprintf(buff + 32, sizeof(buff) - 32, "%c:\\temp\\%s.svp", targetdrv, pkgptr);
280 mateuszvis 767
    if (fcopy(buff + 32, buff, buff, sizeof(buff)) != 0) {
768
      video_putstring(10, 30, COLOR_BODY[mono], "READ ERROR", -1);
192 mateuszvis 769
      input_getkey();
280 mateuszvis 770
      fclose(fd);
192 mateuszvis 771
      return(-1);
55 mv_fox 772
    }
280 mateuszvis 773
    /* write install instruction to post-install script */
700 mateusz.vi 774
    fprintf(fd, "pkg install %s.svp\r\ndel %s.svp\r\n", pkgptr, pkgptr);
192 mateuszvis 775
    /* jump to next entry or end of list */
776
    while ((*pkgptr != 0) && (*pkgptr != 0xff)) pkgptr++;
777
    if (*pkgptr == 0xff) break;
28 mv_fox 778
  }
280 mateuszvis 779
  /* set up locales so the "installation over" message is nicely displayed */
780
  genlocalesconf(fd, locales);
781
  /* replace autoexec.bat and config.sys now and write some nice message on screen */
782
  fprintf(fd, "DEL pkg.exe\r\n"
783
              "COPY CONFIG.SYS C:\\\r\n"
784
              "DEL CONFIG.SYS\r\n"
785
              "DEL C:\\AUTOEXEC.BAT\r\n"
786
              "COPY AUTOEXEC.BAT C:\\\r\n"
787
              "DEL AUTOEXEC.BAT\r\n");
788
  /* print out the "installation over" message */
789
  fprintf(fd, "ECHO.\r\n"
790
              "ECHO %s\r\n"
624 mateuszvis 791
              "ECHO.\r\n", svarlang_strid(0x0501)); /* "SvarDOS installation is over. Please restart your computer now" */
280 mateuszvis 792
  fclose(fd);
793
 
794
  /* prepare a dummy autoexec.bat that will call temp\postinst.bat */
795
  snprintf(buff, sizeof(buff), "%c:\\autoexec.bat", targetdrv);
796
  fd = fopen(buff, "wb");
797
  if (fd == NULL) return(-1);
798
  fprintf(fd, "@ECHO OFF\r\n"
799
              "SET DOSDIR=C:\\SVARDOS\r\n"
800
              "SET NLSPATH=%%DOSDIR%%\\NLS\r\n"
801
              "PATH %%DOSDIR%%\\BIN\r\n");
802
  fprintf(fd, "CD TEMP\r\n"
803
              "postinst.bat\r\n");
804
  fclose(fd);
805
 
192 mateuszvis 806
  return(0);
28 mv_fox 807
}
808
 
809
 
42 mv_fox 810
static void finalreboot(void) {
56 mv_fox 811
  int y = 9;
79 mv_fox 812
  newscreen(2);
624 mateuszvis 813
  y += putstringnls(y, 1, COLOR_BODY[mono], 5, 0); /* "Your computer will reboot now.\nPlease remove the installation disk from your drive" */
814
  putstringnls(++y, 1, COLOR_BODY[mono], 0, 5); /* "Press any key..." */
42 mv_fox 815
  input_getkey();
816
  reboot();
817
}
818
 
819
 
192 mateuszvis 820
static void loadcp(const struct slocales *locales) {
42 mv_fox 821
  char buff[64];
67 mv_fox 822
  if (locales->codepage == 437) return;
42 mv_fox 823
  video_movecursor(1, 0);
67 mv_fox 824
  if (locales->egafile == 1) {
310 mateuszvis 825
    snprintf(buff, sizeof(buff), "MODE CON CP PREP=((%u) EGA.CPX) > NUL", locales->codepage);
42 mv_fox 826
  } else {
310 mateuszvis 827
    snprintf(buff, sizeof(buff), "MODE CON CP PREP=((%u) EGA%d.CPX) > NUL", locales->codepage, locales->egafile);
42 mv_fox 828
  }
829
  system(buff);
67 mv_fox 830
  snprintf(buff, sizeof(buff), "MODE CON CP SEL=%u > NUL", locales->codepage);
42 mv_fox 831
  system(buff);
832
  /* below I re-init the video controller - apparently this is required if
65 mv_fox 833
   * I want the new glyph symbols to be actually applied, at least some
834
   * (broken?) BIOSes, like VBox, apply glyphs only at next video mode change */
42 mv_fox 835
  {
836
  union REGS r;
837
  r.h.ah = 0x0F; /* get current video mode */
838
  int86(0x10, &r, &r); /* r.h.al contains the current video mode now */
56 mv_fox 839
  r.h.al |= 128; /* set the high bit of AL to instruct BIOS not to flush VRAM's content (EGA+) */
840
  r.h.ah = 0; /* re-set video mode (to whatever is set in AL) */
42 mv_fox 841
  int86(0x10, &r, &r);
842
  }
843
}
844
 
200 mateuszvis 845
 
310 mateuszvis 846
#ifdef DEADCODE
193 mateuszvis 847
/* checks that drive drv contains SvarDOS packages
65 mv_fox 848
 * returns 0 if found, non-zero otherwise */
193 mateuszvis 849
static int checkinstsrc(char drv) {
850
  char fname[16];
700 mateusz.vi 851
  snprintf(fname, sizeof(fname), "%c:\\ATTRIB.SVP", drv);
200 mateuszvis 852
  return(fileexists(fname));
69 mv_fox 853
}
310 mateuszvis 854
#endif
65 mv_fox 855
 
856
 
28 mv_fox 857
int main(void) {
67 mv_fox 858
  struct slocales locales;
28 mv_fox 859
  int targetdrv;
193 mateuszvis 860
  int sourcedrv;
73 mv_fox 861
  int action;
28 mv_fox 862
 
310 mateuszvis 863
  sourcedrv = get_cur_drive() + 'A';
53 mv_fox 864
 
29 mv_fox 865
  /* init screen and detect mono status */
866
  mono = video_init();
867
 
73 mv_fox 868
 SelectLang:
190 mateuszvis 869
  action = selectlang(&locales); /* welcome to svardos, select your language */
73 mv_fox 870
  if (action != MENUNEXT) goto Quit;
871
  loadcp(&locales);
624 mateuszvis 872
  svarlang_load("INSTALL", locales.lang, ".\\"); /* NLS support */
73 mv_fox 873
  action = selectkeyb(&locales);  /* what keyb layout should we use? */
874
  if (action == MENUQUIT) goto Quit;
875
  if (action == MENUPREV) goto SelectLang;
876
 
877
 WelcomeScreen:
190 mateuszvis 878
  action = welcomescreen(); /* what svardos is, ask whether to run live dos or install */
73 mv_fox 879
  if (action == MENUQUIT) goto Quit;
880
  if (action == MENUPREV) goto SelectLang;
312 mateuszvis 881
  targetdrv = preparedrive(sourcedrv); /* what drive should we install from? check avail. space */
73 mv_fox 882
  if (targetdrv == MENUQUIT) goto Quit;
883
  if (targetdrv == MENUPREV) goto WelcomeScreen;
280 mateuszvis 884
  bootfilesgen(targetdrv, &locales); /* generate boot files and other configurations */
885
  if (installpackages(targetdrv, sourcedrv, &locales) != 0) goto Quit;    /* install packages */
73 mv_fox 886
  /*localcfg();*/ /* show local params (currency, etc), and propose to change them (based on localcfg) */
887
  /*netcfg();*/ /* basic networking config */
888
  finalreboot(); /* remove the CD and reboot */
889
 
890
 Quit:
81 mv_fox 891
  video_clear(0x0700, 0, 0);
28 mv_fox 892
  video_movecursor(0, 0);
893
  return(0);
894
}